[Feature][T106_eSDK]update from T106-V2.01.01.02P56U06.AP.15.11_CAP.15.11.01 to T106-V2.01.01.02P56U06.AP.17.02_CAP.17.02.02 -- code
Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No
Change-Id: Ib96b45ce27a9cc1e8e774c42334dfb86aa0da634
diff --git a/upstream/linux-5.10/net/8021q/vlan_dev.c b/upstream/linux-5.10/net/8021q/vlan_dev.c
index 86a1c99..6117e9c 100755
--- a/upstream/linux-5.10/net/8021q/vlan_dev.c
+++ b/upstream/linux-5.10/net/8021q/vlan_dev.c
@@ -94,7 +94,7 @@
return NETDEV_TX_OK;
#endif
}
-
+extern void fast_update_indev(struct sk_buff *skb, struct net_device *dev);
static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -120,7 +120,7 @@
len = skb->len;
if (unlikely(netpoll_tx_running(dev)))
return vlan_netpoll_send_skb(vlan, skb);
-
+ fast_update_indev(skb, dev);
ret = dev_queue_xmit(skb);
if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
diff --git a/upstream/linux-5.10/net/bridge/br_fdb.c b/upstream/linux-5.10/net/bridge/br_fdb.c
index 65a6054..974ee5e 100755
--- a/upstream/linux-5.10/net/bridge/br_fdb.c
+++ b/upstream/linux-5.10/net/bridge/br_fdb.c
@@ -1313,7 +1313,7 @@
u16 vid = 0;
int ntl_port_id = 0xff;
- if(!skb->dev)
+ if(!skb->dev || fastbr_level != 1)
{
//print_sun(SUN_DBG, "fast_br skb->dev err skb->dev = %x\n", skb->dev);
return 0;
diff --git a/upstream/linux-5.10/net/core/SI/net_other.c b/upstream/linux-5.10/net/core/SI/net_other.c
index a6748c7..816686b 100755
--- a/upstream/linux-5.10/net/core/SI/net_other.c
+++ b/upstream/linux-5.10/net/core/SI/net_other.c
@@ -1090,7 +1090,8 @@
int fast_local4_output_num = 0; //±¾µØfast_local4³É¹¦·¢Ëͱ¨ÎÄ
int fast_local6_output_num = 0; //±¾µØfast_local6³É¹¦·¢Ëͱ¨ÎÄ
int fast_tcpdump_num = 0; //fast×¥°üÊýÁ¿
-
+int skb_expand4 = 0; //Í·¿Õ¼ä²»¹»ÖØÐÂÉêÇëµÄV4Êý¾Ý°ü
+int skb_expand6 = 0; //Í·¿Õ¼ä²»¹»ÖØÐÂÉêÇëµÄV6Êý¾Ý°ü
int double_mac = 0; //mac¼ì²é¿ª¹Ø
//slabÄÚ´æÊ¹ÓÃÏà¹ØÍ³¼Æ£¬Î´¿¼ÂÇͨÓÃslabµØÖ·³Ø£¬Èçkmalloc
diff --git a/upstream/linux-5.10/net/core/fastproc/fast4_fw.c b/upstream/linux-5.10/net/core/fastproc/fast4_fw.c
index 0ef32e4..a0674f9 100755
--- a/upstream/linux-5.10/net/core/fastproc/fast4_fw.c
+++ b/upstream/linux-5.10/net/core/fastproc/fast4_fw.c
@@ -67,6 +67,7 @@
/* ******************************** º¯ÊýʵÏÖ ********************************/
int dst_expire_count = 0;
extern int no_neighbour;
+extern fast_list_t working_list;
static inline int rt_is_expired(struct rtable *rth)
{
@@ -555,7 +556,11 @@
{
ret = ifname_compare_aligned(ct->indev[dir]->name, ipinfo->iniface, ipinfo->iniface_mask);
}
-
+ else
+ {
+ ret=1;
+ }
+
if(ipinfo->iniface[0] != '\0')
*match_filter = 1;
@@ -583,6 +588,8 @@
ip_packet_match_neg(const struct ipt_ip *ipinfo,struct nf_conn* ct,int dir, int* match_filter)
{
unsigned long ret;
+ if(!(ct->status & IPS_NAT_MASK))
+ return false;
if (NF_INVF(ipinfo, IPT_INV_SRCIP,
(ct->tuplehash[dir].tuple.dst.u3.ip & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) ||
NF_INVF(ipinfo, IPT_INV_DSTIP,
@@ -595,7 +602,11 @@
{
ret = ifname_compare_aligned(ct->outdev[dir]->name, ipinfo->iniface, ipinfo->iniface_mask);
}
-
+ else
+ {
+ ret = 1;
+ }
+
if(ipinfo->iniface[0] != '\0')
*match_filter = 1;
@@ -675,7 +686,7 @@
e = get_entry(table_base, private->hook_entry[NF_INET_LOCAL_IN]);
break;
default:
- break;
+ return;
}
while(num--)
{
@@ -747,8 +758,7 @@
static void ct_iptables_bhfunc(unsigned long param)
{
- int hash = 0;
- struct nf_conntrack_tuple_hash *h;
+ fast_entry_t *ret = NULL;
struct hlist_nulls_node *n;
struct nf_conn *ct;
struct xt_table_info *private;
@@ -756,13 +766,12 @@
unsigned int addend;
local_bh_disable();
addend = xt_write_recseq_begin();
- for(hash = 0; hash < nf_conntrack_htable_size; hash++)
- {
- hlist_nulls_for_each_entry_rcu(h,n,&nf_conntrack_hash[hash],hnnode)
+ spin_lock_bh(&fast_fw_spinlock);
+ for (ret = (&working_list)->next; ret; ret = ret->next)
+ {
+ if(ret)
{
- if(h)
- {
- ct = nf_ct_tuplehash_to_ctrack(h);
+ ct = ret->ct;
if(ct->fast_ct.isFast)
{
net = nf_ct_net(ct);
@@ -777,19 +786,66 @@
}
else
continue;
- spin_lock_bh(&fast_fw_spinlock);
+
ct->packet_info[IP_CT_DIR_ORIGINAL].bytes = 0;
ct->packet_info[IP_CT_DIR_ORIGINAL].packets = 0;
ct->packet_info[IP_CT_DIR_REPLY].bytes = 0;
ct->packet_info[IP_CT_DIR_REPLY].packets = 0;
- spin_unlock_bh(&fast_fw_spinlock);
- }
- }
- }
+ }
+ }
+ spin_unlock_bh(&fast_fw_spinlock);
xt_write_recseq_end(addend);
local_bh_enable();
}
+#if 0
+/*ÐÂfastÏÂiptablesͬ²½µÄ´úÂ루±£Áô£©*/
+/* Started by AICoder, pid:bc328v3b69u30bb14fea08b4d0be594808c2486b */
+static void ct_iptables_bhfunc(unsigned long param)
+{
+ unsigned int addend;
+ local_bh_disable();
+ addend = xt_write_recseq_begin();
+ spin_lock_bh(&fast_fw_spinlock);
+ for(int hash = 0; hash < nf_conntrack_htable_size; hash++)
+ {
+ struct nf_conntrack_tuple_hash *h;
+ struct hlist_nulls_node *n;
+ for_each_rcu_safe(h, n, &nf_conntrack_hash[hash])
+ {
+ if(h)
+ {
+ struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
+ if(ct->fast_ct.isFast)
+ {
+ struct net *net = nf_ct_net(ct);
+ struct xt_table_info *private;
+ const char *chain_names[] = {
+ "IPTABLE_RAW",
+ "IPTABLE_MANGLE",
+ "IPTABLE_NAT",
+ "IPTABLE_FILTER"
+ };
+ for (int i = 0; i < 4; i++) {
+ switch (i) {
+ case 0: private = READ_ONCE(net->ipv4.iptable_raw->private); break;
+ case 1: private = READ_ONCE(net->ipv4.iptable_mangle->private); break;
+ case 2: private = READ_ONCE(net->ipv4.nat_table->private); break;
+ case 3: private = READ_ONCE(net->ipv4.iptable_filter->private); break;
+ }
+ ct_iptables_syn_handle(ct, private, chain_names[i]);
+ }
+ }
+ }
+ }
+ }
+ spin_unlock_bh(&fast_fw_spinlock);
+ xt_write_recseq_end(addend);
+ local_bh_enable();
+}
+/* Ended by AICoder, pid:bc328v3b69u30bb14fea08b4d0be594808c2486b */
+#endif
+
int fast4_fw_init(void)
{
diff --git a/upstream/linux-5.10/net/core/fastproc/fast6.c b/upstream/linux-5.10/net/core/fastproc/fast6.c
index d5fab9c..5beebba 100755
--- a/upstream/linux-5.10/net/core/fastproc/fast6.c
+++ b/upstream/linux-5.10/net/core/fastproc/fast6.c
@@ -207,7 +207,9 @@
__u8 next_hdr = 0;
unsigned char *l4head;
struct ipv6hdr *ip6;
-
+ struct sk_buff *skb2 = NULL;
+ int l4_offset = 0;
+
print_sun(SUN_DBG, "enter fast_6_recv \n");
if (fastnat_level == FAST_CLOSE)
@@ -286,13 +288,18 @@
print_sun(SUN_DBG, "fast_6_recv l4head is null \n");
return 0;
}
-
-
-
- if (!(skb = fast_expand_headroom_v6(skb, dev))){
+ l4_offset = l4head - skb->data;
+
+ if (!(skb2 = fast_expand_headroom_v6(skb, dev))){
rcu_read_unlock();
return 1;
}
+
+ if(skb2 != skb){
+ l4head = skb2->data + l4_offset;
+ skb = skb2;
+ skb_expand6++;
+ }
fast_tcpdump(skb);
@@ -316,8 +323,30 @@
skb->isFastnat = 1;
skb->priority = fast6_entry_data->priority;
skb->mark = fast6_entry_data->mark;
-
-
+ if (likely(skb_get_nfct(skb) == 0)){
+ skb_set_nfct(skb, (unsigned long)fast6_entry->ct);
+ nf_conntrack_get(&fast6_entry->ct->ct_general);
+ }
+ spin_lock_bh(&fast_fw_spinlock);
+ //»ùÓÚctÁ´½ÓµÄÁ÷Á¿Í³¼Æ --- ͳ¼ÆIP°ü²»ÊÇMAC°ü
+ if (fast6_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL){
+ fast6_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].packets++;
+ fast6_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].bytes += skb->len;
+ if(unlikely(fast6_entry->ct->indev[IP_CT_DIR_ORIGINAL] == NULL))
+ fast6_entry->ct->indev[IP_CT_DIR_ORIGINAL] = skb->indev;
+ if(unlikely(fast6_entry->ct->outdev[IP_CT_DIR_ORIGINAL] == NULL))
+ fast6_entry->ct->outdev[IP_CT_DIR_ORIGINAL] = dev;
+ } else if (fast6_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_REPLY){
+ fast6_entry->ct->packet_info[IP_CT_DIR_REPLY].packets++;
+ fast6_entry->ct->packet_info[IP_CT_DIR_REPLY].bytes += skb->len;
+ if(unlikely(fast6_entry->ct->indev[IP_CT_DIR_REPLY] == NULL))
+ fast6_entry->ct->indev[IP_CT_DIR_REPLY] = skb->indev;
+ if(unlikely(fast6_entry->ct->outdev[IP_CT_DIR_REPLY] == NULL))
+ fast6_entry->ct->outdev[IP_CT_DIR_REPLY] = dev;
+ } else {
+ printk("fast6 packet error\n");
+ }
+ spin_unlock_bh(&fast_fw_spinlock);
//ÄÚºË×Ô´øµÄ»ùÓÚÁ´½ÓµÄÁ÷Á¿Í³¼Æ
struct nf_conn_counter *acct = (struct nf_conn_counter*)nf_conn_acct_find(fast6_entry->ct);
if (acct) {
@@ -348,7 +377,8 @@
//Ö»Óе±ÓÐMACÍ·Ô¤¸³ÖµÊ±£¬²Å×¼¸³Öµ£¬·ñÔòΪIPÍ·
skb_push(skb, ETH_HLEN);
-
+
+ if (fast6_entry_data->hh_flag)
memcpy(skb->data, fast6_entry_data->hh_data, ETH_HLEN);
/*¸üÐÂÁ¬½Ó³¬Ê±*/
if (IPPROTO_TCP == tuple.dst.protonum)
@@ -470,12 +500,12 @@
return NF_ACCEPT;
}
_neighbour = dst_neigh_lookup_skb(dst, skb);
- if(!_neighbour)
- {
- return NF_ACCEPT;
+ if(_neighbour == NULL && ((ipv6_addr_type(&ipv6_hdr(skb)->daddr)) == IPV6_ADDR_ANY
+ || ((ipv6_addr_type(&ipv6_hdr(skb)->daddr)) & IPV6_ADDR_LOOPBACK))){
+ return NF_ACCEPT;
}
- if (memcmp(_neighbour->ha, zeromac, ETH_ALEN) == 0)
+ if (_neighbour && memcmp(_neighbour->ha, zeromac, ETH_ALEN) == 0)
{
goto accept;
}
@@ -536,9 +566,10 @@
fast6_entry_data = &fast6_entry->data[dir];
fast6_entry_data->tuplehash.tuple = ct->tuplehash[dir].tuple;
- memcpy(fast6_entry_data->dmac, _neighbour->ha, ETH_ALEN);
+ //memcpy(fast6_entry_data->dmac, _neighbour->ha, ETH_ALEN);
fast6_entry_data->priority = skb->priority;
fast6_entry_data->mark = skb->mark;
+ if(fast6_entry_data->outdev == NULL){
fast6_entry_data->outdev = out;
if (!record_MAC_header(working_hash6, ct, fast6_entry, fast6_entry_data, _neighbour, out, htons(ETH_P_IPV6)))
@@ -546,7 +577,7 @@
spin_unlock_bh(&fast6_spinlock);
goto accept;
}
-
+ }
//´Ë´¦±£Ö¤Õý·´Á½¸ö±ê¼Çλ²»³åÍ»
fast6_entry->flags = fast6_entry->flags | (1 << dir);
@@ -563,7 +594,7 @@
ct->fast_ct.isFast = FAST_CT_WND6;
accept:
-
+ if(_neighbour)
neigh_release(_neighbour);
return NF_ACCEPT;
}
diff --git a/upstream/linux-5.10/net/core/fastproc/fast6_fw.c b/upstream/linux-5.10/net/core/fastproc/fast6_fw.c
index 322175b..ec21bc6 100755
--- a/upstream/linux-5.10/net/core/fastproc/fast6_fw.c
+++ b/upstream/linux-5.10/net/core/fastproc/fast6_fw.c
@@ -40,8 +40,23 @@
#include <net/SI/net_cache.h>
#include <net/SI/print_sun.h>
+#include <linux/netfilter/xt_tcpudp.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+
+
MODULE_LICENSE("GPL");
+static struct task_struct *ct_ip6tables_syn;
+static struct tasklet_struct ct_ip6tables_bh;
+extern unsigned int ct_iptables_syn_sw;
+enum table6_index {
+ IP6TABLE_RAW,
+ IP6TABLE_MANGLE,
+ IP6TABLE_NAT,
+ IP6TABLE_FILTER
+};
+
+
/* ***************** ipv6 ¿ìËÙת·¢Ïà¹Ø±äÁ¿ ************************* */
@@ -53,6 +68,7 @@
int dst_expire_count_v6 = 0;
extern int no_neighbour;
+extern fast_list_t working_list6;
extern void ntl_ct_set_iw(struct sk_buff *skb, struct nf_conn *ct, int ct_dir);
int fast6_fw_recv(struct nf_conn *tmpl,
struct sk_buff *skb,
@@ -163,7 +179,8 @@
skb->isFastnat = 1;
nf_ct_set(skb, (struct nf_conn *)&ct->ct_general, ctinfo);
-
+ ct->packet_info[dir].packets++;
+ ct->packet_info[dir].bytes += skb->len;
//»ùÓÚÍø¿ÚµÄÁ÷Á¿Í³¼Æ --- ²Î¿¼linuxÔÉúµÄÇý¶¯£¬Í³¼ÆµÄ¶¼ÊÇIP°ü³¤¶È
if (fastnat_level == FAST_NET_DEVICE)
{
@@ -203,6 +220,17 @@
}
skb->dev = dev;
skb->now_location |= FASTNAT_SUCC;
+
+ if(ct->indev[dir] == NULL && skb->indev != NULL)
+ {
+ ct->indev[dir] = skb->indev;
+ }
+
+ if(ct->outdev[dir] == NULL && skb->dev != NULL)
+ {
+ ct->outdev[dir] = skb->dev;
+ }
+
skb->vlan_proto = vlan_proto_raw;
skb->vlan_tci = vlan_tci_raw;
__flush_dcache_area(skb->data, skb->len);
@@ -370,6 +398,372 @@
.priority = NF_IP6_PRI_LAST,
};
+static inline bool
+port_match(u_int16_t min, u_int16_t max, u_int16_t port, bool invert)
+{
+ return (port >= min && port <= max) ^ invert;
+}
+
+static bool ctable_mt(struct nf_conn* ct, struct xt_action_param *par,int dir, int* match_filter)
+{
+ const struct xt_tcp *tcpinfo = par->matchinfo;
+
+ if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1],
+ ntohs(ct->tuplehash[dir].tuple.src.u.tcp.port),
+ !!(tcpinfo->invflags & XT_TCP_INV_SRCPT)))
+ return false;
+ if((tcpinfo->spts[0] || tcpinfo->spts[1]) ^ (!!(tcpinfo->invflags & XT_TCP_INV_SRCPT)))
+ *match_filter = 1;
+ if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1],
+ ntohs(ct->tuplehash[dir].tuple.dst.u.tcp.port),
+ !!(tcpinfo->invflags & XT_TCP_INV_DSTPT)))
+ return false;
+ if((tcpinfo->dpts[0] || tcpinfo->dpts[1]) ^ (!!(tcpinfo->invflags & XT_TCP_INV_DSTPT)))
+ *match_filter = 1;
+ return true;
+}
+
+static inline bool
+ip6_packet_match(const struct ip6t_ip6 *ip6info,struct nf_conn* ct,int dir, int* match_filter)
+{
+ unsigned long ret;
+ if (NF_INVF(ip6info, IP6T_INV_SRCIP,
+ ipv6_masked_addr_cmp((struct in6_addr *)(ct->tuplehash[dir].tuple.src.u3.ip6), &ip6info->smsk,
+ &ip6info->src)) ||
+ NF_INVF(ip6info, IP6T_INV_DSTIP,
+ ipv6_masked_addr_cmp((struct in6_addr *)(ct->tuplehash[dir].tuple.dst.u3.ip6), &ip6info->dmsk,
+ &ip6info->dst)))
+ return false;
+ if(ip6info->src.in6_u.u6_addr32[0] || ip6info->dst.in6_u.u6_addr32[0])
+ {
+ *match_filter = 1;
+ }
+
+ if(ct->indev[dir] != NULL)
+ {
+ ret = ifname_compare_aligned(ct->indev[dir]->name, ip6info->iniface, ip6info->iniface_mask);
+ }
+ else
+ {
+ ret=1;
+ }
+
+ if(ip6info->iniface[0] != '\0')
+ *match_filter = 1;
+
+ if (NF_INVF(ip6info, IP6T_INV_VIA_IN, ret != 0))
+ return false;
+ if(ct->outdev[dir] != NULL)
+ {
+ ret = ifname_compare_aligned(ct->outdev[dir]->name, ip6info->outiface, ip6info->outiface_mask);
+ }
+
+ if(ip6info->outiface[0] != '\0')
+ *match_filter = 1;
+
+ if (NF_INVF(ip6info, IP6T_INV_VIA_OUT, ret != 0))
+ return false;
+
+ if (ip6info->flags & IP6T_F_PROTO) {
+ int protohdr;
+
+ protohdr = ct->tuplehash[dir].tuple.dst.protonum;
+
+ if (ip6info->proto == protohdr) {
+ if (ip6info->invflags & IP6T_INV_PROTO)
+ return false;
+
+ return true;
+ }
+
+ /* We need match for the '-p all', too! */
+ if ((ip6info->proto != 0) &&
+ !(ip6info->invflags & IP6T_INV_PROTO))
+ return false;
+ }
+
+ return true;
+}
+
+static inline bool
+ip6_packet_match_neg(const struct ip6t_ip6 *ip6info,struct nf_conn* ct,int dir, int* match_filter)
+{
+ unsigned long ret;
+ if(!(ct->status & IPS_NAT_MASK))
+ return false;
+ if (NF_INVF(ip6info, IP6T_INV_SRCIP,
+ ipv6_masked_addr_cmp((struct in6_addr *)ct->tuplehash[dir].tuple.src.u3.ip6, &ip6info->smsk,
+ &ip6info->src)) ||
+ NF_INVF(ip6info, IP6T_INV_DSTIP,
+ ipv6_masked_addr_cmp((struct in6_addr *)ct->tuplehash[dir].tuple.dst.u3.ip6, &ip6info->dmsk,
+ &ip6info->dst)))
+ return false;
+ if(ip6info->src.in6_u.u6_addr32[0] || ip6info->dst.in6_u.u6_addr32[0])
+ *match_filter = 1;
+
+ if(ct->outdev[dir] != NULL)
+ {
+ ret = ifname_compare_aligned(ct->outdev[dir]->name, ip6info->iniface, ip6info->iniface_mask);
+ }
+ else
+ {
+ ret = 1;
+ }
+
+ if(ip6info->iniface[0] != '\0')
+ *match_filter = 1;
+
+ if (NF_INVF(ip6info, IP6T_INV_VIA_IN, ret != 0))
+ return false;
+ if(ct->indev[dir] != NULL)
+ {
+ ret = ifname_compare_aligned(ct->indev[dir]->name, ip6info->outiface, ip6info->outiface_mask);
+ }
+
+ if(ip6info->outiface[0] != '\0')
+ *match_filter = 1;
+
+ if (NF_INVF(ip6info, IP6T_INV_VIA_OUT, ret != 0))
+ return false;
+
+ if (ip6info->flags & IP6T_F_PROTO) {
+ int protohdr;
+
+ protohdr = ct->tuplehash[dir].tuple.dst.protonum;
+
+ if (ip6info->proto == protohdr) {
+ if (ip6info->invflags & IP6T_INV_PROTO)
+ return false;
+
+ return true;
+ }
+
+ /* We need match for the '-p all', too! */
+ if ((ip6info->proto != 0) &&
+ !(ip6info->invflags & IP6T_INV_PROTO))
+ return false;
+ }
+
+ return true;
+}
+
+static inline struct ip6t_entry *
+get_entry(const void *base, unsigned int offset)
+{
+ return (struct ip6t_entry *)(base + offset);
+}
+
+static inline
+struct ip6t_entry *ip6t_next_entry(const struct ip6t_entry *entry)
+{
+ return (void *)entry + entry->next_offset;
+}
+
+
+
+//ͬ²½ctͳ¼ÆÐÅÏ¢µ½iptables,ͬ²½ÖÜÆÚÔݶ¨1s
+static int ct_ip6tables_syn_thread(void *param)
+{
+ while (1)
+ {
+ if(ct_iptables_syn_sw)
+ {
+ rcu_read_lock();
+ tasklet_schedule(&ct_ip6tables_bh);
+ rcu_read_unlock();
+ //ÿ´Îͬ²½¼ä¸ôΪ1s.
+ }
+ msleep(1*1000);
+ }
+ return 0;
+}
+
+void ct_ip6tables_syn_handle(struct nf_conn *ct,struct xt_table_info *private,int table_id)
+{
+ void *table_base;
+ struct ip6t_entry *e;
+ const struct xt_entry_match *ematch;
+ struct xt_action_param acpar;
+ struct xt_counters *counter;
+ int match_flag = 0;
+ int match_filter = 0;
+ int num = 0;
+
+
+ table_base = private->entries;
+ num = private->number;
+ switch(table_id)
+ {
+ case 0:
+ case 1:
+ case 2:
+ e = get_entry(table_base, private->hook_entry[NF_INET_PRE_ROUTING]);
+ break;
+ case 3:
+ e = get_entry(table_base, private->hook_entry[NF_INET_LOCAL_IN]);
+ break;
+ default:
+ return;
+ }
+ while(num--)
+ {
+ match_flag = 0;
+ match_filter = 0;
+ if(!ip6_packet_match(&e->ipv6, ct, IP_CT_DIR_ORIGINAL,&match_filter) &&
+ !ip6_packet_match_neg(&e->ipv6, ct, IP_CT_DIR_REPLY,&match_filter))
+ {
+ }
+ else
+ {
+ xt_ematch_foreach(ematch, e)
+ {
+ acpar.matchinfo = ematch->data;
+ if (!ctable_mt(ct, &acpar, IP_CT_DIR_ORIGINAL,&match_filter))
+ {
+ match_flag = 1;
+ break;
+ }
+ else
+ {
+ }
+ }
+ if(!match_flag)
+ {
+ if(match_filter)
+ {
+ counter = xt_get_this_cpu_counter(&e->counters);
+ ADD_COUNTER(*counter, ct->packet_info[IP_CT_DIR_ORIGINAL].bytes,ct->packet_info[IP_CT_DIR_ORIGINAL].packets);
+ }
+ e = ip6t_next_entry(e);
+ continue;
+ }
+ match_flag = 0;
+ match_filter = 0;
+ }
+
+ if (!ip6_packet_match(&e->ipv6, ct, IP_CT_DIR_REPLY,&match_filter) &&
+ !ip6_packet_match_neg(&e->ipv6, ct, IP_CT_DIR_ORIGINAL,&match_filter))
+ {
+ e = ip6t_next_entry(e);
+ continue;
+ }
+ else
+ {
+ xt_ematch_foreach(ematch, e)
+ {
+ acpar.matchinfo = ematch->data;
+ if (!ctable_mt(ct, &acpar, IP_CT_DIR_REPLY,&match_filter))
+ {
+ match_flag = 1;
+ break;
+ }
+ }
+ if(!match_flag)
+ {
+ if(match_filter)
+ {
+ counter = xt_get_this_cpu_counter(&e->counters);
+ ADD_COUNTER(*counter, ct->packet_info[IP_CT_DIR_REPLY].bytes,ct->packet_info[IP_CT_DIR_REPLY].packets);
+ }
+ e = ip6t_next_entry(e);
+ continue;
+ }
+ }
+ }
+
+}
+
+static void ct_ip6tables_bhfunc(unsigned long param)
+{
+ fast_entry_t *ret = NULL;
+ struct hlist_nulls_node *n;
+ struct nf_conn *ct;
+ struct xt_table_info *private;
+ struct net * net;
+ unsigned int addend;
+ local_bh_disable();
+ addend = xt_write_recseq_begin();
+ spin_lock_bh(&fast_fw_spinlock);
+ for (ret = (&working_list6)->next; ret; ret = ret->next)
+ {
+ if(ret)
+ {
+ ct = ret->ct;
+ if(ct->fast_ct.isFast)
+ {
+ net = nf_ct_net(ct);
+ private = READ_ONCE(net->ipv6.ip6table_raw->private);
+ ct_ip6tables_syn_handle(ct,private,IP6TABLE_RAW);
+ private = READ_ONCE(net->ipv6.ip6table_mangle->private);
+ ct_ip6tables_syn_handle(ct,private,IP6TABLE_MANGLE);
+ private = READ_ONCE(net->ipv6.ip6table_nat->private);
+ ct_ip6tables_syn_handle(ct,private,IP6TABLE_NAT);
+ private = READ_ONCE(net->ipv6.ip6table_filter->private);
+ ct_ip6tables_syn_handle(ct,private,IP6TABLE_FILTER);
+ }
+ else
+ continue;
+
+ ct->packet_info[IP_CT_DIR_ORIGINAL].bytes = 0;
+ ct->packet_info[IP_CT_DIR_ORIGINAL].packets = 0;
+ ct->packet_info[IP_CT_DIR_REPLY].bytes = 0;
+ ct->packet_info[IP_CT_DIR_REPLY].packets = 0;
+ }
+ }
+ spin_unlock_bh(&fast_fw_spinlock);
+ xt_write_recseq_end(addend);
+ local_bh_enable();
+}
+
+#if 0
+/*ÐÂfast ip6tablesÁ÷Á¿Í¬²½´úÂë,±£Áô*/
+/* Started by AICoder, pid:b1b62d7ef7md76714807099a103c224334833109 */
+static void ct_ip6tables_bhfunc(unsigned long param)
+{
+ int hash;
+ struct nf_conn *ct;
+ struct xt_table_info *private;
+ struct net *net;
+ unsigned int addend;
+ local_bh_disable();
+ addend = xt_write_recseq_begin();
+ for(hash = 0; hash < nf_conntrack_htable_size; hash++)
+ {
+ struct nf_conntrack_tuple_hash *h;
+ struct hlist_nulls_node *n;
+ hlist_nulls_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnnode)
+ {
+ if(h)
+ {
+ ct = nf_ct_tuplehash_to_ctrack(h);
+ if(ct->fast_ct.isFast)
+ {
+ net = nf_ct_net(ct);
+ private = READ_ONCE(net->ipv6.ip6table_raw->private);
+ ct_ip6tables_syn_handle(ct, private, IP6TABLE_RAW);
+ private = READ_ONCE(net->ipv6.ip6table_mangle->private);
+ ct_ip6tables_syn_handle(ct, private, IP6TABLE_MANGLE);
+ private = READ_ONCE(net->ipv6.ip6table_nat->private);
+ ct_ip6tables_syn_handle(ct, private, IP6TABLE_NAT);
+ private = READ_ONCE(net->ipv6.ip6table_filter->private);
+ ct_ip6tables_syn_handle(ct, private, IP6TABLE_FILTER);
+ spin_lock_bh(&fast_fw_spinlock);
+ for(int i = 0; i < 4; i++)
+ {
+ ct->packet_info[i].bytes = 0;
+ ct->packet_info[i].packets = 0;
+ }
+ spin_unlock_bh(&fast_fw_spinlock);
+ }
+ }
+ }
+ }
+ xt_write_recseq_end(addend);
+ local_bh_enable();
+}
+/* Ended by AICoder, pid:b1b62d7ef7md76714807099a103c224334833109 */
+#endif
+
int fast6_fw_init(void)
{
@@ -383,6 +777,14 @@
}
print_sun(SUN_DBG,"init fast6_fw_init done\n");
+ ct_ip6tables_bh.func = ct_ip6tables_bhfunc;
+ ct_ip6tables_syn = kthread_create(ct_ip6tables_syn_thread, (void *)0, "ct_ip6tables_syn" );
+ if (!IS_ERR(ct_ip6tables_syn))
+ {
+ printk("ntl_syn_task thread's init is succ");
+ wake_up_process(ct_ip6tables_syn);
+ }
+
return 0;
}
@@ -390,6 +792,12 @@
{
fast_release_all(RELEASE_ALL_DST);
nf_unregister_net_hook(&init_net, &fast6_fw_hook);
+ if (ct_ip6tables_syn)
+ {
+ kthread_stop(ct_ip6tables_syn);
+ ct_ip6tables_syn = NULL;
+ }
+ tasklet_kill(&ct_ip6tables_bh);
return 0;
}
diff --git a/upstream/linux-5.10/net/core/fastproc/fast_common.c b/upstream/linux-5.10/net/core/fastproc/fast_common.c
index 69f3761..80ad864 100755
--- a/upstream/linux-5.10/net/core/fastproc/fast_common.c
+++ b/upstream/linux-5.10/net/core/fastproc/fast_common.c
@@ -621,7 +621,7 @@
//²Î¿¼ip6_xmit,À©³äskbÍ·²¿
struct sk_buff *fast_expand_headroom_v6(struct sk_buff *skb, struct net_device *dev) {
- unsigned int hh_len = LL_RESERVED_SPACE(dev) + sizeof(struct ipv6hdr);
+ unsigned int hh_len = LL_RESERVED_SPACE(dev);//EC616000622279½â¾öv6ÉÏÐÐÊý¾Ý°üÓÉÓÚÍ·¿Õ¼ä²»¹»ÖØÐÂÉêÇëµÄÎÊÌâ + sizeof(struct ipv6hdr);
struct sk_buff *skb2 = NULL;
if (unlikely(skb_headroom(skb) < hh_len)) {
skb2 = skb_realloc_headroom(skb, max(hh_len, NET_SKB_PAD));
@@ -726,6 +726,9 @@
{
tcpack_rel(entry);
//nf_ct_put(entry->ct);
+ spin_lock_bh(&fast_fw_spinlock);
+ entry->ct->fast_entry = NULL;
+ spin_unlock_bh(&fast_fw_spinlock);
atomic_dec(&(entry->ct->ct_general.use));
fn_list_del(list_head, entry);
}
@@ -810,6 +813,7 @@
netslab_inc(FAST_SLAB);
memset(ret, 0, sizeof(fast_entry_t));
ret->ct = ct;
+ ct->fast_entry = ret;
ret->list_head = list_head;
//ÉèÖö¨Ê±Æ÷
@@ -897,7 +901,7 @@
goto REL;
//½ö¶ÔÒÔÌ«ÍøÀàÍø¿Ú½øÐÐMACÍ·Ô¤¸³Öµ£¬ÆäËüµÄÈçPPP¡¢PPPoEÕâЩ£¬½ÔÊǿɱäµÄ£¬²»ÄÜÔ¤¸³Öµ£»²Î¼ûalloc_netdevºÍalloc_etherdev½Ó¿Ú
- if (out->type != ARPHRD_ETHER)
+ if (out->type != ARPHRD_ETHER || neigh == NULL)
return 1;
//¶ÔÓÚ³ö¿ÚÎªÍøÇÅbrʱ£¬Ö±½Ó»ñÈ¡L2ÍøÂçÉ豸£¬¼´usb0»òwifi0
@@ -906,7 +910,7 @@
if(out->dev_addr == NULL)
goto REL;
- if (fastbr_level == 1)
+ if (fastbr_level)
{
dst_out = getbrport_bydst(out, neigh->ha);
if (dst_out == NULL)
@@ -964,6 +968,9 @@
//»Ö¸´ctµÄ³¬Ê±
//add_timer(&ct->timeout);
//nf_ct_put(ct);
+ spin_lock_bh(&fast_fw_spinlock);
+ entry->ct->fast_entry = NULL;
+ spin_unlock_bh(&fast_fw_spinlock);
atomic_dec(&(ct->ct_general.use));
del_timer(&entry->timeout);
fn_list_del(entry->list_head, entry);
@@ -1079,7 +1086,9 @@
del_timer(&entry->timeout);
workinghash_del_node(entry);
-
+ spin_lock_bh(&fast_fw_spinlock);
+ entry->ct->fast_entry = NULL;
+ spin_unlock_bh(&fast_fw_spinlock);
//»Ö¸´ctµÄ³¬Ê±
//add_timer(&entry->ct->timeout);
fn_list_del(list_head, entry);
@@ -1552,7 +1561,7 @@
return 1;
}
//vlan
- else if (next_pro == cpu_to_be16(ETH_P_8021Q))
+ else if (next_pro == cpu_to_be16(ETH_P_8021Q) && fastbr_level == 1)
{
skb->isvlan = 1;
skb_pull(skb, VLAN_HLEN);
@@ -1591,7 +1600,7 @@
//if (((unsigned long)skb->data)%4 != 0)
//panic("ERR: fast from dev skb->data%4 != 0");
- if (skb->indev == NULL)
+ if (skb->indev == NULL || is_vlan_dev(skb->dev))
skb->indev = skb->dev;
//ÐèҪ׼ȷ¶¨Î»µ½IPÍ·£¬ÆÚ¼ä¿ÉÄÜÌø¹ýppp/mac/pppoeµÈ¸÷ÖÖ²ã2Í·²¿
if (set_skbdata_toip(skb) == 1 && fast_for_ipdata(skb))
@@ -2055,6 +2064,21 @@
return dst;
}
+void fast_update_indev(struct sk_buff *skb, struct net_device *dev)
+{
+ if(fastbr_level != 1 && skb->isFastnat == 1){
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+
+ if(ct){
+ if(ct->indev[0] == skb->indev && ct->indev[1] == NULL)
+ ct->indev[1] = dev;
+ if(ct->indev[1] == skb->indev && ct->indev[0] == NULL)
+ ct->indev[0] = dev;
+ }
+ }
+}
+
/*fast³õʼ»¯*/
static int __init
tsp_fast_init(void)
diff --git a/upstream/linux-5.10/net/core/fastproc/fast_track.c b/upstream/linux-5.10/net/core/fastproc/fast_track.c
index 37f3cfc..712ff6d 100755
--- a/upstream/linux-5.10/net/core/fastproc/fast_track.c
+++ b/upstream/linux-5.10/net/core/fastproc/fast_track.c
@@ -234,7 +234,7 @@
if (copy_from_user(char_fastbr, buffer, 1))
return -EFAULT;
- if (char_fastbr[0] < '0' || char_fastbr[0] > '1')
+ if (char_fastbr[0] < '0' || char_fastbr[0] > '2')
return -EINVAL;
fastbr_level = (int)(char_fastbr[0] - '0');
@@ -252,8 +252,8 @@
{
if (*pos == 0)
{
- seq_printf(seq, "fastnat have %d conn!!!\nskb_num4:%d,fastnat_num:%d\n",
- working_list.count, skb_num4, fastnat_num);
+ seq_printf(seq, "fastnat have %d conn!!!\nskb_num4:%d,fastnat_num:%d,expand_head4:%d\n",
+ working_list.count, skb_num4, fastnat_num, skb_expand4);
seq_printf(seq, "fastbr_sum:%d,fastbr_num:%d\n",
skb_num4 + skb_num6 + skb_unknown - fastnat_num - fast6_num, fastbr_num);
@@ -399,8 +399,8 @@
working_list.count,fastnat_recv_count,fastnat_real_count);
seq_printf(seq, "send_2_ps_failed:%u, send_2_usb_failed:%u\n", send_2_ps_failed, send_2_usb_failed);
#endif
- seq_printf(seq, "fast6 have %d conn!!!\nskb_num6:%d,fast6_num:%d\n",
- working_list6.count, skb_num6, fast6_num);
+ seq_printf(seq, "fast6 have %d conn!!!\nskb_num6:%d,fast6_num:%d,expand_head6:%d\n",
+ working_list6.count, skb_num6, fast6_num, skb_expand6);
}
return &working_hash6[*pos];
}
@@ -1160,6 +1160,42 @@
.proc_write = ct_iptables_syn_set,
};
+/* Started by AICoder, pid:i2747j1887i1a311479909db709e49391b4455c1 */
+static ssize_t dev_unreg_set(struct file *file, const char __user *buffer, size_t count, loff_t *pos)
+{
+ struct net_device *dev = NULL;
+ size_t size;
+ char dev_name[MAX_NET_DEVICE_NAME_LEN + 1] = {0};
+
+ // Ensure that the string is null-terminated
+ if (count == 0 || count > MAX_NET_DEVICE_NAME_LEN + 1)
+ return -EINVAL;
+
+ // Copy the device name from user space and ensure it's null terminated
+ size = min(count - 1, MAX_NET_DEVICE_NAME_LEN);
+ if (copy_from_user(dev_name, buffer, size)) {
+ return -EFAULT;
+ }
+ dev_name[size] = '\0'; // Ensure null-termination
+
+ // Try to get the network device by name
+ dev = dev_get_by_name(&init_net, dev_name);
+ if (dev) {
+ // Put the device reference
+ dev_put(dev);
+ // Unregister the network device
+ unregister_netdev(dev);
+ } else {
+ printk("dev_unreg %s not found\n", dev_name);
+ }
+
+ return count;
+}
+
+static const struct proc_ops dev_unreg_file_ops = {
+ .proc_write = dev_unreg_set,
+};
+/* Ended by AICoder, pid:i2747j1887i1a311479909db709e49391b4455c1 */
//¿ìËÙת·¢procÎļþµÄ³õʼ»¯
int fast_conntrack_init_proc(void)
@@ -1195,6 +1231,7 @@
proc_create("dev_reset_stats", 0440, init_net.proc_net, &dev_reset_file_ops);
proc_create("ct_iptables_syn", 0440, init_net.proc_net, &ct_iptables_syn_file_ops);
+ proc_create("dev_unreg", 0440, init_net.proc_net, &dev_unreg_file_ops);
return 1;
}
diff --git a/upstream/linux-5.10/net/core/fastproc/fastnat.c b/upstream/linux-5.10/net/core/fastproc/fastnat.c
index 717454c..8d585c0 100755
--- a/upstream/linux-5.10/net/core/fastproc/fastnat.c
+++ b/upstream/linux-5.10/net/core/fastproc/fastnat.c
@@ -209,6 +209,7 @@
{
iph = (struct iphdr *)skb2->data;
skb = skb2;
+ skb_expand4++;
}
fast_tcpdump(skb);
@@ -275,7 +276,8 @@
skb->priority = nat_entry_data->priority;
skb->mark = nat_entry_data->mark;
-
+
+ spin_lock_bh(&fast_fw_spinlock);
//»ùÓÚctÁ´½ÓµÄÁ÷Á¿Í³¼Æ --- ͳ¼ÆIP°ü²»ÊÇMAC°ü
if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL){
nat_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].packets++;
@@ -294,6 +296,7 @@
} else {
printk("fastnat packet error\n");
}
+ spin_unlock_bh(&fast_fw_spinlock);
//ÄÚºË×Ô´øµÄ»ùÓÚÁ´½ÓµÄÁ÷Á¿Í³¼Æ
struct nf_conn_counter *acct = (struct nf_conn_counter *)nf_conn_acct_find((const struct nf_conn *)nat_entry->ct);
@@ -450,7 +453,8 @@
}
//¹ã²¥¡¢×é²¥²»½¨Á´
- if (ipv4_is_multicast(ip_hdr(skb)->daddr) || ipv4_is_lbcast(ip_hdr(skb)->daddr))
+ if (ipv4_is_multicast(ip_hdr(skb)->daddr) || ipv4_is_lbcast(ip_hdr(skb)->daddr)
+ || ip_hdr(skb)->daddr == 0 || ip_hdr(skb)->saddr == 0)
{
return NF_ACCEPT;
}
@@ -467,13 +471,10 @@
}
_neighbour = dst_neigh_lookup_skb(dst, skb);
- if (!_neighbour)
- {
- print_sun(SUN_DBG,"napt_handle() _neighbour = null\n");
+ if(_neighbour == NULL && ((ip_hdr(skb)->daddr & 0xff000000) == 0xff000000 )){
return NF_ACCEPT;
- }
-
- if (memcmp(_neighbour->ha, zeromac, ETH_ALEN) == 0)
+ }
+ if (_neighbour && memcmp(_neighbour->ha, zeromac, ETH_ALEN) == 0)
{
if (strncmp(out->name, ppp_name, strlen(ppp_name)) != 0)
{
@@ -557,9 +558,10 @@
entry_data = &nat_entry->data[dir];
entry_data->tuplehash.tuple = ct->tuplehash[dir].tuple;
- memcpy(entry_data->dmac, _neighbour->ha, ETH_ALEN);
+ //memcpy(entry_data->dmac, _neighbour->ha, ETH_ALEN);
entry_data->priority = skb->priority;
entry_data->mark = skb->mark;
+ if(entry_data->outdev == NULL){
entry_data->outdev = out;
/*¼Ç¼MACµØÖ·µ½entry_data->hh_data*/
@@ -568,6 +570,7 @@
spin_unlock_bh(&fastnat_spinlock);
goto accept;
}
+ }
print_sun(SUN_DBG,"napt_handle() ct->status=0x%x\n", ct->status);
/*»ñÈ¡natת»»ÐèÒªµÄIPºÍportÐÅÏ¢*/
if (test_bit(IPS_SRC_NAT_BIT, &ct->status))
@@ -624,6 +627,7 @@
spin_unlock_bh(&fastnat_spinlock);
accept:
+ if(_neighbour)
neigh_release(_neighbour);
return NF_ACCEPT;
}
diff --git a/upstream/linux-5.10/net/netfilter/nf_conntrack_core.c b/upstream/linux-5.10/net/netfilter/nf_conntrack_core.c
index e92413e..d4ae0b7 100755
--- a/upstream/linux-5.10/net/netfilter/nf_conntrack_core.c
+++ b/upstream/linux-5.10/net/netfilter/nf_conntrack_core.c
@@ -1621,6 +1621,11 @@
ct->packet_info[IP_CT_DIR_ORIGINAL].bytes = 0;
ct->packet_info[IP_CT_DIR_REPLY].packets = 0;
ct->packet_info[IP_CT_DIR_REPLY].bytes = 0;
+ ct->indev[IP_CT_DIR_ORIGINAL] = NULL;
+ ct->outdev[IP_CT_DIR_ORIGINAL] = NULL;
+ ct->indev[IP_CT_DIR_REPLY] = NULL;
+ ct->outdev[IP_CT_DIR_REPLY] = NULL;
+ ct->fast_entry = NULL;
for(dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++)
{
ct->indev[dir] = NULL;