blob: 16cbed35720045849892b3319709806d6b8032af [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001/* This program is free software; you can redistribute it and/or modify
2 * it under the terms of the GNU General Public License as published by
3 * the Free Software Foundation; version 2 of the License
4 *
5 * This program is distributed in the hope that it will be useful,
6 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 * GNU General Public License for more details.
9 *
10 * Copyright (C) 2014-2016 Sean Wang <sean.wang@mediatek.com>
11 * Copyright (C) 2016-2017 John Crispin <blogic@openwrt.org>
12 */
13
14#include <linux/netfilter_bridge.h>
15#include <linux/netfilter_ipv6.h>
16
17#include <net/arp.h>
18#include <net/neighbour.h>
19#include <net/netfilter/nf_conntrack_helper.h>
20#include <net/netfilter/nf_flow_table.h>
21#include <net/ipv6.h>
22#include <net/ip6_route.h>
23#include <net/ip.h>
24#include <net/tcp.h>
25#include <net/udp.h>
developer30a47682021-11-02 17:06:14 +080026#include <net/netfilter/nf_conntrack.h>
27#include <net/netfilter/nf_conntrack_acct.h>
developerfd40db22021-04-29 10:08:25 +080028
29#include "nf_hnat_mtk.h"
30#include "hnat.h"
31
32#include "../mtk_eth_soc.h"
developer8051e042022-04-08 13:26:36 +080033#include "../mtk_eth_reset.h"
developerfd40db22021-04-29 10:08:25 +080034
35#define do_ge2ext_fast(dev, skb) \
developerd35bbcc2022-09-28 22:46:01 +080036 ((IS_LAN_GRP(dev) || IS_WAN(dev) || IS_PPD(dev)) && \
developerfd40db22021-04-29 10:08:25 +080037 skb_hnat_is_hashed(skb) && \
38 skb_hnat_reason(skb) == HIT_BIND_FORCE_TO_CPU)
39#define do_ext2ge_fast_learn(dev, skb) \
40 (IS_PPD(dev) && \
41 (skb_hnat_sport(skb) == NR_PDMA_PORT || \
42 skb_hnat_sport(skb) == NR_QDMA_PORT) && \
43 ((get_dev_from_index(skb->vlan_tci & VLAN_VID_MASK)) || \
44 get_wandev_from_index(skb->vlan_tci & VLAN_VID_MASK)))
45#define do_mape_w2l_fast(dev, skb) \
46 (mape_toggle && IS_WAN(dev) && (!is_from_mape(skb)))
47
48static struct ipv6hdr mape_l2w_v6h;
49static struct ipv6hdr mape_w2l_v6h;
50static inline uint8_t get_wifi_hook_if_index_from_dev(const struct net_device *dev)
51{
52 int i;
53
54 for (i = 1; i < MAX_IF_NUM; i++) {
55 if (hnat_priv->wifi_hook_if[i] == dev)
56 return i;
57 }
58
59 return 0;
60}
61
62static inline int get_ext_device_number(void)
63{
64 int i, number = 0;
65
66 for (i = 0; i < MAX_EXT_DEVS && hnat_priv->ext_if[i]; i++)
67 number += 1;
68 return number;
69}
70
71static inline int find_extif_from_devname(const char *name)
72{
73 int i;
74 struct extdev_entry *ext_entry;
75
76 for (i = 0; i < MAX_EXT_DEVS && hnat_priv->ext_if[i]; i++) {
77 ext_entry = hnat_priv->ext_if[i];
78 if (!strcmp(name, ext_entry->name))
79 return 1;
80 }
81 return 0;
82}
83
84static inline int get_index_from_dev(const struct net_device *dev)
85{
86 int i;
87 struct extdev_entry *ext_entry;
88
89 for (i = 0; i < MAX_EXT_DEVS && hnat_priv->ext_if[i]; i++) {
90 ext_entry = hnat_priv->ext_if[i];
91 if (dev == ext_entry->dev)
92 return ext_entry->dev->ifindex;
93 }
94 return 0;
95}
96
97static inline struct net_device *get_dev_from_index(int index)
98{
99 int i;
100 struct extdev_entry *ext_entry;
101 struct net_device *dev = 0;
102
103 for (i = 0; i < MAX_EXT_DEVS && hnat_priv->ext_if[i]; i++) {
104 ext_entry = hnat_priv->ext_if[i];
105 if (ext_entry->dev && index == ext_entry->dev->ifindex) {
106 dev = ext_entry->dev;
107 break;
108 }
109 }
110 return dev;
111}
112
113static inline struct net_device *get_wandev_from_index(int index)
114{
developer8c9c0d02021-06-18 16:15:37 +0800115 if (!hnat_priv->g_wandev)
116 hnat_priv->g_wandev = dev_get_by_name(&init_net, hnat_priv->wan);
developerfd40db22021-04-29 10:08:25 +0800117
developer8c9c0d02021-06-18 16:15:37 +0800118 if (hnat_priv->g_wandev && hnat_priv->g_wandev->ifindex == index)
119 return hnat_priv->g_wandev;
developerfd40db22021-04-29 10:08:25 +0800120 return NULL;
121}
122
123static inline int extif_set_dev(struct net_device *dev)
124{
125 int i;
126 struct extdev_entry *ext_entry;
127
128 for (i = 0; i < MAX_EXT_DEVS && hnat_priv->ext_if[i]; i++) {
129 ext_entry = hnat_priv->ext_if[i];
130 if (!strcmp(dev->name, ext_entry->name) && !ext_entry->dev) {
131 dev_hold(dev);
132 ext_entry->dev = dev;
133 pr_info("%s(%s)\n", __func__, dev->name);
134
135 return ext_entry->dev->ifindex;
136 }
137 }
138
139 return -1;
140}
141
142static inline int extif_put_dev(struct net_device *dev)
143{
144 int i;
145 struct extdev_entry *ext_entry;
146
147 for (i = 0; i < MAX_EXT_DEVS && hnat_priv->ext_if[i]; i++) {
148 ext_entry = hnat_priv->ext_if[i];
149 if (ext_entry->dev == dev) {
150 ext_entry->dev = NULL;
151 dev_put(dev);
152 pr_info("%s(%s)\n", __func__, dev->name);
153
developerbc53e5f2021-05-21 10:07:17 +0800154 return 0;
developerfd40db22021-04-29 10:08:25 +0800155 }
156 }
157
158 return -1;
159}
160
161int ext_if_add(struct extdev_entry *ext_entry)
162{
163 int len = get_ext_device_number();
164
developer4c32b7a2021-11-13 16:46:43 +0800165 if (len < MAX_EXT_DEVS)
166 hnat_priv->ext_if[len++] = ext_entry;
167
developerfd40db22021-04-29 10:08:25 +0800168 return len;
169}
170
171int ext_if_del(struct extdev_entry *ext_entry)
172{
173 int i, j;
174
175 for (i = 0; i < MAX_EXT_DEVS; i++) {
176 if (hnat_priv->ext_if[i] == ext_entry) {
177 for (j = i; hnat_priv->ext_if[j] && j < MAX_EXT_DEVS - 1; j++)
178 hnat_priv->ext_if[j] = hnat_priv->ext_if[j + 1];
179 hnat_priv->ext_if[j] = NULL;
180 break;
181 }
182 }
183
184 return i;
185}
186
187void foe_clear_all_bind_entries(struct net_device *dev)
188{
developer471f6562021-05-10 20:48:34 +0800189 int i, hash_index;
developerfd40db22021-04-29 10:08:25 +0800190 struct foe_entry *entry;
191
developerd35bbcc2022-09-28 22:46:01 +0800192 if (!IS_LAN_GRP(dev) && !IS_WAN(dev) &&
developerfd40db22021-04-29 10:08:25 +0800193 !find_extif_from_devname(dev->name) &&
194 !dev->netdev_ops->ndo_flow_offload_check)
195 return;
196
developer471f6562021-05-10 20:48:34 +0800197 for (i = 0; i < CFG_PPE_NUM; i++) {
198 cr_set_field(hnat_priv->ppe_base[i] + PPE_TB_CFG,
199 SMA, SMA_ONLY_FWD_CPU);
200
201 for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
202 entry = hnat_priv->foe_table_cpu[i] + hash_index;
203 if (entry->bfib1.state == BIND) {
204 entry->ipv4_hnapt.udib1.state = INVALID;
205 entry->ipv4_hnapt.udib1.time_stamp =
206 readl((hnat_priv->fe_base + 0x0010)) & 0xFF;
207 }
developerfd40db22021-04-29 10:08:25 +0800208 }
209 }
210
211 /* clear HWNAT cache */
212 hnat_cache_ebl(1);
213
214 mod_timer(&hnat_priv->hnat_sma_build_entry_timer, jiffies + 3 * HZ);
215}
216
217static void gmac_ppe_fwd_enable(struct net_device *dev)
218{
219 if (IS_LAN(dev) || IS_GMAC1_MODE)
developerd35bbcc2022-09-28 22:46:01 +0800220 set_gmac_ppe_fwd(NR_GMAC1_PORT, 1);
developerfd40db22021-04-29 10:08:25 +0800221 else if (IS_WAN(dev))
developerd35bbcc2022-09-28 22:46:01 +0800222 set_gmac_ppe_fwd(NR_GMAC2_PORT, 1);
223 else if (IS_LAN2(dev))
224 set_gmac_ppe_fwd(NR_GMAC3_PORT, 1);
developerfd40db22021-04-29 10:08:25 +0800225}
226
227int nf_hnat_netdevice_event(struct notifier_block *unused, unsigned long event,
228 void *ptr)
229{
230 struct net_device *dev;
231
232 dev = netdev_notifier_info_to_dev(ptr);
233
234 switch (event) {
235 case NETDEV_UP:
236 gmac_ppe_fwd_enable(dev);
237
238 extif_set_dev(dev);
239
240 break;
241 case NETDEV_GOING_DOWN:
242 if (!get_wifi_hook_if_index_from_dev(dev))
243 extif_put_dev(dev);
244
245 foe_clear_all_bind_entries(dev);
246
247 break;
developer8c9c0d02021-06-18 16:15:37 +0800248 case NETDEV_UNREGISTER:
developer1901f412022-01-04 17:22:00 +0800249 if (hnat_priv->g_ppdev == dev) {
developer8c9c0d02021-06-18 16:15:37 +0800250 hnat_priv->g_ppdev = NULL;
251 dev_put(dev);
252 }
developer1901f412022-01-04 17:22:00 +0800253 if (hnat_priv->g_wandev == dev) {
developer8c9c0d02021-06-18 16:15:37 +0800254 hnat_priv->g_wandev = NULL;
255 dev_put(dev);
256 }
257
258 break;
259 case NETDEV_REGISTER:
260 if (IS_PPD(dev) && !hnat_priv->g_ppdev)
261 hnat_priv->g_ppdev = dev_get_by_name(&init_net, hnat_priv->ppd);
262 if (IS_WAN(dev) && !hnat_priv->g_wandev)
263 hnat_priv->g_wandev = dev_get_by_name(&init_net, hnat_priv->wan);
264
265 break;
developer8051e042022-04-08 13:26:36 +0800266 case MTK_FE_RESET_NAT_DONE:
267 pr_info("[%s] HNAT driver starts to do warm init !\n", __func__);
268 hnat_warm_init();
269 break;
developerfd40db22021-04-29 10:08:25 +0800270 default:
271 break;
272 }
273
274 return NOTIFY_DONE;
275}
276
277void foe_clear_entry(struct neighbour *neigh)
278{
279 u32 *daddr = (u32 *)neigh->primary_key;
280 unsigned char h_dest[ETH_ALEN];
281 struct foe_entry *entry;
developer471f6562021-05-10 20:48:34 +0800282 int i, hash_index;
developerfd40db22021-04-29 10:08:25 +0800283 u32 dip;
284
285 dip = (u32)(*daddr);
286
developer471f6562021-05-10 20:48:34 +0800287 for (i = 0; i < CFG_PPE_NUM; i++) {
developer8051e042022-04-08 13:26:36 +0800288 if (!hnat_priv->foe_table_cpu[i])
289 continue;
290
developer471f6562021-05-10 20:48:34 +0800291 for (hash_index = 0; hash_index < hnat_priv->foe_etry_num; hash_index++) {
292 entry = hnat_priv->foe_table_cpu[i] + hash_index;
293 if (entry->bfib1.state == BIND &&
294 entry->ipv4_hnapt.new_dip == ntohl(dip)) {
295 *((u32 *)h_dest) = swab32(entry->ipv4_hnapt.dmac_hi);
296 *((u16 *)&h_dest[4]) =
297 swab16(entry->ipv4_hnapt.dmac_lo);
298 if (strncmp(h_dest, neigh->ha, ETH_ALEN) != 0) {
299 pr_info("%s: state=%d\n", __func__,
300 neigh->nud_state);
301 cr_set_field(hnat_priv->ppe_base[i] + PPE_TB_CFG,
302 SMA, SMA_ONLY_FWD_CPU);
developerfd40db22021-04-29 10:08:25 +0800303
developer471f6562021-05-10 20:48:34 +0800304 entry->ipv4_hnapt.udib1.state = INVALID;
305 entry->ipv4_hnapt.udib1.time_stamp =
306 readl((hnat_priv->fe_base + 0x0010)) & 0xFF;
developerfd40db22021-04-29 10:08:25 +0800307
developer471f6562021-05-10 20:48:34 +0800308 /* clear HWNAT cache */
309 hnat_cache_ebl(1);
developerfd40db22021-04-29 10:08:25 +0800310
developer471f6562021-05-10 20:48:34 +0800311 mod_timer(&hnat_priv->hnat_sma_build_entry_timer,
312 jiffies + 3 * HZ);
developerfd40db22021-04-29 10:08:25 +0800313
developer471f6562021-05-10 20:48:34 +0800314 pr_info("Delete old entry: dip =%pI4\n", &dip);
315 pr_info("Old mac= %pM\n", h_dest);
316 pr_info("New mac= %pM\n", neigh->ha);
317 }
developerfd40db22021-04-29 10:08:25 +0800318 }
319 }
320 }
321}
322
323int nf_hnat_netevent_handler(struct notifier_block *unused, unsigned long event,
324 void *ptr)
325{
326 struct net_device *dev = NULL;
327 struct neighbour *neigh = NULL;
328
329 switch (event) {
330 case NETEVENT_NEIGH_UPDATE:
331 neigh = ptr;
332 dev = neigh->dev;
333 if (dev)
334 foe_clear_entry(neigh);
335 break;
336 }
337
338 return NOTIFY_DONE;
339}
340
341unsigned int mape_add_ipv6_hdr(struct sk_buff *skb, struct ipv6hdr mape_ip6h)
342{
343 struct ethhdr *eth = NULL;
344 struct ipv6hdr *ip6h = NULL;
345 struct iphdr *iph = NULL;
346
347 if (skb_headroom(skb) < IPV6_HDR_LEN || skb_shared(skb) ||
348 (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
349 return -1;
350 }
351
352 /* point to L3 */
353 memcpy(skb->data - IPV6_HDR_LEN - ETH_HLEN, skb_push(skb, ETH_HLEN), ETH_HLEN);
354 memcpy(skb_push(skb, IPV6_HDR_LEN - ETH_HLEN), &mape_ip6h, IPV6_HDR_LEN);
355
356 eth = (struct ethhdr *)(skb->data - ETH_HLEN);
357 eth->h_proto = htons(ETH_P_IPV6);
358 skb->protocol = htons(ETH_P_IPV6);
359
360 iph = (struct iphdr *)(skb->data + IPV6_HDR_LEN);
361 ip6h = (struct ipv6hdr *)(skb->data);
362 ip6h->payload_len = iph->tot_len; /* maybe different with ipv4 */
363
364 skb_set_network_header(skb, 0);
365 skb_set_transport_header(skb, iph->ihl * 4 + IPV6_HDR_LEN);
366 return 0;
367}
368
369static void fix_skb_packet_type(struct sk_buff *skb, struct net_device *dev,
370 struct ethhdr *eth)
371{
372 skb->pkt_type = PACKET_HOST;
373 if (unlikely(is_multicast_ether_addr(eth->h_dest))) {
374 if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast))
375 skb->pkt_type = PACKET_BROADCAST;
376 else
377 skb->pkt_type = PACKET_MULTICAST;
378 }
379}
380
381unsigned int do_hnat_ext_to_ge(struct sk_buff *skb, const struct net_device *in,
382 const char *func)
383{
384 if (hnat_priv->g_ppdev && hnat_priv->g_ppdev->flags & IFF_UP) {
385 u16 vlan_id = 0;
386 skb_set_network_header(skb, 0);
387 skb_push(skb, ETH_HLEN);
388 set_to_ppe(skb);
389
390 vlan_id = skb_vlan_tag_get_id(skb);
391 if (vlan_id) {
392 skb = vlan_insert_tag(skb, skb->vlan_proto, skb->vlan_tci);
393 if (!skb)
394 return -1;
395 }
396
397 /*set where we come from*/
398 skb->vlan_proto = htons(ETH_P_8021Q);
399 skb->vlan_tci =
400 (VLAN_CFI_MASK | (in->ifindex & VLAN_VID_MASK));
401 trace_printk(
402 "%s: vlan_prot=0x%x, vlan_tci=%x, in->name=%s, skb->dev->name=%s\n",
403 __func__, ntohs(skb->vlan_proto), skb->vlan_tci,
404 in->name, hnat_priv->g_ppdev->name);
405 skb->dev = hnat_priv->g_ppdev;
406 dev_queue_xmit(skb);
407 trace_printk("%s: called from %s successfully\n", __func__, func);
408 return 0;
409 }
410
411 trace_printk("%s: called from %s fail\n", __func__, func);
412 return -1;
413}
414
415unsigned int do_hnat_ext_to_ge2(struct sk_buff *skb, const char *func)
416{
417 struct ethhdr *eth = eth_hdr(skb);
418 struct net_device *dev;
419 struct foe_entry *entry;
420
421 trace_printk("%s: vlan_prot=0x%x, vlan_tci=%x\n", __func__,
422 ntohs(skb->vlan_proto), skb->vlan_tci);
423
developer577ad2f2022-11-28 10:33:36 +0800424 if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
425 skb_hnat_ppe(skb) >= CFG_PPE_NUM)
426 return -1;
427
developerfd40db22021-04-29 10:08:25 +0800428 dev = get_dev_from_index(skb->vlan_tci & VLAN_VID_MASK);
429
430 if (dev) {
431 /*set where we to go*/
432 skb->dev = dev;
433 skb->vlan_proto = 0;
434 skb->vlan_tci = 0;
435
436 if (ntohs(eth->h_proto) == ETH_P_8021Q) {
437 skb = skb_vlan_untag(skb);
438 if (unlikely(!skb))
439 return -1;
440 }
441
442 if (IS_BOND_MODE &&
developer4164cfe2022-12-01 11:27:41 +0800443 (((hnat_priv->data->version == MTK_HNAT_V2 ||
444 hnat_priv->data->version == MTK_HNAT_V3) &&
developerfd40db22021-04-29 10:08:25 +0800445 (skb_hnat_entry(skb) != 0x7fff)) ||
developer4164cfe2022-12-01 11:27:41 +0800446 ((hnat_priv->data->version != MTK_HNAT_V2 &&
447 hnat_priv->data->version != MTK_HNAT_V3) &&
developerfd40db22021-04-29 10:08:25 +0800448 (skb_hnat_entry(skb) != 0x3fff))))
449 skb_set_hash(skb, skb_hnat_entry(skb) >> 1, PKT_HASH_TYPE_L4);
450
451 set_from_extge(skb);
452 fix_skb_packet_type(skb, skb->dev, eth);
453 netif_rx(skb);
454 trace_printk("%s: called from %s successfully\n", __func__,
455 func);
456 return 0;
457 } else {
458 /* MapE WAN --> LAN/WLAN PingPong. */
459 dev = get_wandev_from_index(skb->vlan_tci & VLAN_VID_MASK);
460 if (mape_toggle && dev) {
461 if (!mape_add_ipv6_hdr(skb, mape_w2l_v6h)) {
462 skb_set_mac_header(skb, -ETH_HLEN);
463 skb->dev = dev;
464 set_from_mape(skb);
465 skb->vlan_proto = 0;
466 skb->vlan_tci = 0;
467 fix_skb_packet_type(skb, skb->dev, eth_hdr(skb));
developer471f6562021-05-10 20:48:34 +0800468 entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
developerfd40db22021-04-29 10:08:25 +0800469 entry->bfib1.pkt_type = IPV4_HNAPT;
470 netif_rx(skb);
471 return 0;
472 }
473 }
474 trace_printk("%s: called from %s fail\n", __func__, func);
475 return -1;
476 }
477}
478
479unsigned int do_hnat_ge_to_ext(struct sk_buff *skb, const char *func)
480{
481 /*set where we to go*/
482 u8 index;
483 struct foe_entry *entry;
484 struct net_device *dev;
485
developer577ad2f2022-11-28 10:33:36 +0800486 if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
487 skb_hnat_ppe(skb) >= CFG_PPE_NUM)
488 return -1;
489
developer471f6562021-05-10 20:48:34 +0800490 entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
developerfd40db22021-04-29 10:08:25 +0800491
492 if (IS_IPV4_GRP(entry))
493 index = entry->ipv4_hnapt.act_dp;
494 else
495 index = entry->ipv6_5t_route.act_dp;
496
developerdce18f52023-03-18 22:11:13 +0800497 dev = get_dev_from_index(index);
498 if (!dev) {
499 trace_printk("%s: called from %s. Get wifi interface fail\n",
500 __func__, func);
501 return 0;
502 }
503
504 skb->dev = dev;
developerfd40db22021-04-29 10:08:25 +0800505
developer34028fb2022-01-11 13:51:29 +0800506 if (IS_HQOS_MODE && eth_hdr(skb)->h_proto == HQOS_MAGIC_TAG) {
developerfd40db22021-04-29 10:08:25 +0800507 skb = skb_unshare(skb, GFP_ATOMIC);
508 if (!skb)
509 return NF_ACCEPT;
510
511 if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
512 return NF_ACCEPT;
513
514 skb_pull_rcsum(skb, VLAN_HLEN);
515
516 memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - VLAN_HLEN,
517 2 * ETH_ALEN);
518 }
developerfd40db22021-04-29 10:08:25 +0800519
520 if (skb->dev) {
521 skb_set_network_header(skb, 0);
522 skb_push(skb, ETH_HLEN);
523 dev_queue_xmit(skb);
524 trace_printk("%s: called from %s successfully\n", __func__,
525 func);
526 return 0;
527 } else {
528 if (mape_toggle) {
529 /* Add ipv6 header mape for lan/wlan -->wan */
530 dev = get_wandev_from_index(index);
531 if (dev) {
532 if (!mape_add_ipv6_hdr(skb, mape_l2w_v6h)) {
533 skb_set_network_header(skb, 0);
534 skb_push(skb, ETH_HLEN);
535 skb_set_mac_header(skb, 0);
536 skb->dev = dev;
537 dev_queue_xmit(skb);
538 return 0;
539 }
540 trace_printk("%s: called from %s fail[MapE]\n", __func__,
541 func);
542 return -1;
543 }
544 }
545 }
546 /*if external devices is down, invalidate related ppe entry*/
547 if (entry_hnat_is_bound(entry)) {
548 entry->bfib1.state = INVALID;
549 if (IS_IPV4_GRP(entry))
550 entry->ipv4_hnapt.act_dp = 0;
551 else
552 entry->ipv6_5t_route.act_dp = 0;
553
554 /* clear HWNAT cache */
555 hnat_cache_ebl(1);
556 }
557 trace_printk("%s: called from %s fail, index=%x\n", __func__,
558 func, index);
559 return -1;
560}
561
562static void pre_routing_print(struct sk_buff *skb, const struct net_device *in,
563 const struct net_device *out, const char *func)
564{
565 trace_printk(
566 "[%s]: %s(iif=0x%x CB2=0x%x)-->%s (ppe_hash=0x%x) sport=0x%x reason=0x%x alg=0x%x from %s\n",
567 __func__, in->name, skb_hnat_iface(skb),
568 HNAT_SKB_CB2(skb)->magic, out->name, skb_hnat_entry(skb),
569 skb_hnat_sport(skb), skb_hnat_reason(skb), skb_hnat_alg(skb),
570 func);
571}
572
573static void post_routing_print(struct sk_buff *skb, const struct net_device *in,
574 const struct net_device *out, const char *func)
575{
576 trace_printk(
577 "[%s]: %s(iif=0x%x, CB2=0x%x)-->%s (ppe_hash=0x%x) sport=0x%x reason=0x%x alg=0x%x from %s\n",
578 __func__, in->name, skb_hnat_iface(skb),
579 HNAT_SKB_CB2(skb)->magic, out->name, skb_hnat_entry(skb),
580 skb_hnat_sport(skb), skb_hnat_reason(skb), skb_hnat_alg(skb),
581 func);
582}
583
584static inline void hnat_set_iif(const struct nf_hook_state *state,
585 struct sk_buff *skb, int val)
586{
developer40017972021-06-29 14:27:35 +0800587 if (IS_WHNAT(state->in) && FROM_WED(skb)) {
developere567ad32021-05-25 17:16:17 +0800588 return;
589 } else if (IS_LAN(state->in)) {
developerfd40db22021-04-29 10:08:25 +0800590 skb_hnat_iface(skb) = FOE_MAGIC_GE_LAN;
developerd35bbcc2022-09-28 22:46:01 +0800591 } else if (IS_LAN2(state->in)) {
592 skb_hnat_iface(skb) = FOE_MAGIC_GE_LAN2;
developerfd40db22021-04-29 10:08:25 +0800593 } else if (IS_PPD(state->in)) {
594 skb_hnat_iface(skb) = FOE_MAGIC_GE_PPD;
595 } else if (IS_EXT(state->in)) {
596 skb_hnat_iface(skb) = FOE_MAGIC_EXT;
597 } else if (IS_WAN(state->in)) {
598 skb_hnat_iface(skb) = FOE_MAGIC_GE_WAN;
developerfd40db22021-04-29 10:08:25 +0800599 } else if (!IS_BR(state->in)) {
developer99506e52021-06-30 22:03:02 +0800600 if (state->in->netdev_ops->ndo_flow_offload_check) {
601 skb_hnat_iface(skb) = FOE_MAGIC_GE_VIRTUAL;
602 } else {
603 skb_hnat_iface(skb) = FOE_INVALID;
developerfd40db22021-04-29 10:08:25 +0800604
developer99506e52021-06-30 22:03:02 +0800605 if (is_magic_tag_valid(skb) &&
606 IS_SPACE_AVAILABLE_HEAD(skb))
607 memset(skb_hnat_info(skb), 0, FOE_INFO_LEN);
608 }
developerfd40db22021-04-29 10:08:25 +0800609 }
610}
611
612static inline void hnat_set_alg(const struct nf_hook_state *state,
613 struct sk_buff *skb, int val)
614{
615 skb_hnat_alg(skb) = val;
616}
617
618static inline void hnat_set_head_frags(const struct nf_hook_state *state,
619 struct sk_buff *head_skb, int val,
620 void (*fn)(const struct nf_hook_state *state,
621 struct sk_buff *skb, int val))
622{
623 struct sk_buff *segs = skb_shinfo(head_skb)->frag_list;
624
625 fn(state, head_skb, val);
626 while (segs) {
627 fn(state, segs, val);
628 segs = segs->next;
629 }
630}
631
developer25fc8c02022-05-06 16:24:02 +0800632static void ppe_fill_flow_lbl(struct foe_entry *entry, struct ipv6hdr *ip6h)
633{
634 entry->ipv4_dslite.flow_lbl[0] = ip6h->flow_lbl[2];
635 entry->ipv4_dslite.flow_lbl[1] = ip6h->flow_lbl[1];
636 entry->ipv4_dslite.flow_lbl[2] = ip6h->flow_lbl[0];
637}
638
developerfd40db22021-04-29 10:08:25 +0800639unsigned int do_hnat_mape_w2l_fast(struct sk_buff *skb, const struct net_device *in,
640 const char *func)
641{
642 struct ipv6hdr *ip6h = ipv6_hdr(skb);
643 struct iphdr _iphdr;
644 struct iphdr *iph;
645 struct ethhdr *eth;
646
647 /* WAN -> LAN/WLAN MapE. */
648 if (mape_toggle && (ip6h->nexthdr == NEXTHDR_IPIP)) {
649 iph = skb_header_pointer(skb, IPV6_HDR_LEN, sizeof(_iphdr), &_iphdr);
developer4c32b7a2021-11-13 16:46:43 +0800650 if (unlikely(!iph))
651 return -1;
652
developerfd40db22021-04-29 10:08:25 +0800653 switch (iph->protocol) {
654 case IPPROTO_UDP:
655 case IPPROTO_TCP:
656 break;
657 default:
658 return -1;
659 }
660 mape_w2l_v6h = *ip6h;
661
662 /* Remove ipv6 header. */
663 memcpy(skb->data + IPV6_HDR_LEN - ETH_HLEN,
664 skb->data - ETH_HLEN, ETH_HLEN);
665 skb_pull(skb, IPV6_HDR_LEN - ETH_HLEN);
666 skb_set_mac_header(skb, 0);
667 skb_set_network_header(skb, ETH_HLEN);
668 skb_set_transport_header(skb, ETH_HLEN + sizeof(_iphdr));
669
670 eth = eth_hdr(skb);
671 eth->h_proto = htons(ETH_P_IP);
672 set_to_ppe(skb);
673
674 skb->vlan_proto = htons(ETH_P_8021Q);
675 skb->vlan_tci =
676 (VLAN_CFI_MASK | (in->ifindex & VLAN_VID_MASK));
677
678 if (!hnat_priv->g_ppdev)
679 hnat_priv->g_ppdev = dev_get_by_name(&init_net, hnat_priv->ppd);
680
681 skb->dev = hnat_priv->g_ppdev;
682 skb->protocol = htons(ETH_P_IP);
683
684 dev_queue_xmit(skb);
685
686 return 0;
687 }
688 return -1;
689}
690
developer25fc8c02022-05-06 16:24:02 +0800691
developer25fc8c02022-05-06 16:24:02 +0800692
developerfd40db22021-04-29 10:08:25 +0800693static unsigned int is_ppe_support_type(struct sk_buff *skb)
694{
695 struct ethhdr *eth = NULL;
696 struct iphdr *iph = NULL;
697 struct ipv6hdr *ip6h = NULL;
698 struct iphdr _iphdr;
699
700 eth = eth_hdr(skb);
developerfd2d7422021-06-09 17:09:39 +0800701 if (!is_magic_tag_valid(skb) || !IS_SPACE_AVAILABLE_HEAD(skb) ||
developerb254f762022-01-20 20:06:25 +0800702 is_broadcast_ether_addr(eth->h_dest))
developerfd40db22021-04-29 10:08:25 +0800703 return 0;
704
705 switch (ntohs(skb->protocol)) {
706 case ETH_P_IP:
707 iph = ip_hdr(skb);
708
709 /* do not accelerate non tcp/udp traffic */
710 if ((iph->protocol == IPPROTO_TCP) ||
711 (iph->protocol == IPPROTO_UDP) ||
712 (iph->protocol == IPPROTO_IPV6)) {
713 return 1;
714 }
715
716 break;
717 case ETH_P_IPV6:
718 ip6h = ipv6_hdr(skb);
719
720 if ((ip6h->nexthdr == NEXTHDR_TCP) ||
721 (ip6h->nexthdr == NEXTHDR_UDP)) {
722 return 1;
723 } else if (ip6h->nexthdr == NEXTHDR_IPIP) {
724 iph = skb_header_pointer(skb, IPV6_HDR_LEN,
725 sizeof(_iphdr), &_iphdr);
developer4c32b7a2021-11-13 16:46:43 +0800726 if (unlikely(!iph))
727 return 0;
developerfd40db22021-04-29 10:08:25 +0800728
729 if ((iph->protocol == IPPROTO_TCP) ||
730 (iph->protocol == IPPROTO_UDP)) {
731 return 1;
732 }
733
734 }
735
736 break;
737 case ETH_P_8021Q:
738 return 1;
739 }
740
741 return 0;
742}
743
744static unsigned int
745mtk_hnat_ipv6_nf_pre_routing(void *priv, struct sk_buff *skb,
746 const struct nf_hook_state *state)
747{
developer577ad2f2022-11-28 10:33:36 +0800748 if (!skb)
749 goto drop;
750
developerfd40db22021-04-29 10:08:25 +0800751 if (!is_ppe_support_type(skb)) {
752 hnat_set_head_frags(state, skb, 1, hnat_set_alg);
753 return NF_ACCEPT;
754 }
755
756 hnat_set_head_frags(state, skb, -1, hnat_set_iif);
757
758 pre_routing_print(skb, state->in, state->out, __func__);
759
developerfd40db22021-04-29 10:08:25 +0800760 /* packets from external devices -> xxx ,step 1 , learning stage & bound stage*/
761 if (do_ext2ge_fast_try(state->in, skb)) {
762 if (!do_hnat_ext_to_ge(skb, state->in, __func__))
763 return NF_STOLEN;
developerfd40db22021-04-29 10:08:25 +0800764 return NF_ACCEPT;
765 }
766
767 /* packets form ge -> external device
768 * For standalone wan interface
769 */
770 if (do_ge2ext_fast(state->in, skb)) {
771 if (!do_hnat_ge_to_ext(skb, __func__))
772 return NF_STOLEN;
773 goto drop;
774 }
775
developerf4c370a2022-10-08 17:01:19 +0800776
777#if !(defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3))
developerfd40db22021-04-29 10:08:25 +0800778 /* MapE need remove ipv6 header and pingpong. */
779 if (do_mape_w2l_fast(state->in, skb)) {
780 if (!do_hnat_mape_w2l_fast(skb, state->in, __func__))
781 return NF_STOLEN;
782 else
783 return NF_ACCEPT;
784 }
785
786 if (is_from_mape(skb))
787 clr_from_extge(skb);
developerf4c370a2022-10-08 17:01:19 +0800788#endif
developerfd40db22021-04-29 10:08:25 +0800789 return NF_ACCEPT;
790drop:
developer577ad2f2022-11-28 10:33:36 +0800791 if (skb)
792 printk_ratelimited(KERN_WARNING
793 "%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x,\n"
794 "sport=0x%x, reason=0x%x, alg=0x%x)\n",
795 __func__, state->in->name, skb_hnat_iface(skb),
796 HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
797 skb_hnat_sport(skb), skb_hnat_reason(skb),
798 skb_hnat_alg(skb));
developerfd40db22021-04-29 10:08:25 +0800799
800 return NF_DROP;
801}
802
803static unsigned int
804mtk_hnat_ipv4_nf_pre_routing(void *priv, struct sk_buff *skb,
805 const struct nf_hook_state *state)
806{
developer577ad2f2022-11-28 10:33:36 +0800807 if (!skb)
808 goto drop;
809
developerfd40db22021-04-29 10:08:25 +0800810 if (!is_ppe_support_type(skb)) {
811 hnat_set_head_frags(state, skb, 1, hnat_set_alg);
812 return NF_ACCEPT;
813 }
814
815 hnat_set_head_frags(state, skb, -1, hnat_set_iif);
816
817 pre_routing_print(skb, state->in, state->out, __func__);
818
developerfd40db22021-04-29 10:08:25 +0800819 /* packets from external devices -> xxx ,step 1 , learning stage & bound stage*/
820 if (do_ext2ge_fast_try(state->in, skb)) {
821 if (!do_hnat_ext_to_ge(skb, state->in, __func__))
822 return NF_STOLEN;
developerfd40db22021-04-29 10:08:25 +0800823 return NF_ACCEPT;
824 }
825
826 /* packets form ge -> external device
827 * For standalone wan interface
828 */
829 if (do_ge2ext_fast(state->in, skb)) {
830 if (!do_hnat_ge_to_ext(skb, __func__))
831 return NF_STOLEN;
832 goto drop;
833 }
834
835 return NF_ACCEPT;
836drop:
developer577ad2f2022-11-28 10:33:36 +0800837 if (skb)
838 printk_ratelimited(KERN_WARNING
839 "%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x,\n"
840 "sport=0x%x, reason=0x%x, alg=0x%x)\n",
841 __func__, state->in->name, skb_hnat_iface(skb),
842 HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
843 skb_hnat_sport(skb), skb_hnat_reason(skb),
844 skb_hnat_alg(skb));
developerfd40db22021-04-29 10:08:25 +0800845
846 return NF_DROP;
847}
848
849static unsigned int
850mtk_hnat_br_nf_local_in(void *priv, struct sk_buff *skb,
851 const struct nf_hook_state *state)
852{
developerfd40db22021-04-29 10:08:25 +0800853 struct vlan_ethhdr *veth;
854
developer577ad2f2022-11-28 10:33:36 +0800855 if (!skb)
856 goto drop;
857
developer34028fb2022-01-11 13:51:29 +0800858 if (IS_HQOS_MODE && hnat_priv->data->whnat) {
developerfd40db22021-04-29 10:08:25 +0800859 veth = (struct vlan_ethhdr *)skb_mac_header(skb);
860
861 if (eth_hdr(skb)->h_proto == HQOS_MAGIC_TAG) {
862 skb_hnat_entry(skb) = ntohs(veth->h_vlan_TCI) & 0x3fff;
863 skb_hnat_reason(skb) = HIT_BIND_FORCE_TO_CPU;
864 }
865 }
developerfd40db22021-04-29 10:08:25 +0800866
867 if (!HAS_HQOS_MAGIC_TAG(skb) && !is_ppe_support_type(skb)) {
868 hnat_set_head_frags(state, skb, 1, hnat_set_alg);
869 return NF_ACCEPT;
870 }
871
872 hnat_set_head_frags(state, skb, -1, hnat_set_iif);
873
874 pre_routing_print(skb, state->in, state->out, __func__);
875
876 if (unlikely(debug_level >= 7)) {
877 hnat_cpu_reason_cnt(skb);
878 if (skb_hnat_reason(skb) == dbg_cpu_reason)
879 foe_dump_pkt(skb);
880 }
881
developerfd40db22021-04-29 10:08:25 +0800882 /* packets from external devices -> xxx ,step 1 , learning stage & bound stage*/
883 if ((skb_hnat_iface(skb) == FOE_MAGIC_EXT) && !is_from_extge(skb) &&
884 !is_multicast_ether_addr(eth_hdr(skb)->h_dest)) {
885 if (!hnat_priv->g_ppdev)
886 hnat_priv->g_ppdev = dev_get_by_name(&init_net, hnat_priv->ppd);
887
888 if (!do_hnat_ext_to_ge(skb, state->in, __func__))
889 return NF_STOLEN;
developerfd40db22021-04-29 10:08:25 +0800890 return NF_ACCEPT;
891 }
892
893 if (hnat_priv->data->whnat) {
894 if (skb_hnat_iface(skb) == FOE_MAGIC_EXT)
895 clr_from_extge(skb);
896
897 /* packets from external devices -> xxx ,step 2, learning stage */
developeraf07fad2021-11-19 17:53:42 +0800898 if (do_ext2ge_fast_learn(state->in, skb) && (!qos_toggle ||
899 (qos_toggle && eth_hdr(skb)->h_proto != HQOS_MAGIC_TAG))) {
developerfd40db22021-04-29 10:08:25 +0800900 if (!do_hnat_ext_to_ge2(skb, __func__))
901 return NF_STOLEN;
902 goto drop;
903 }
904
905 /* packets form ge -> external device */
906 if (do_ge2ext_fast(state->in, skb)) {
907 if (!do_hnat_ge_to_ext(skb, __func__))
908 return NF_STOLEN;
909 goto drop;
910 }
911 }
912
developerf4c370a2022-10-08 17:01:19 +0800913#if !(defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3))
developerfd40db22021-04-29 10:08:25 +0800914 /* MapE need remove ipv6 header and pingpong. (bridge mode) */
915 if (do_mape_w2l_fast(state->in, skb)) {
916 if (!do_hnat_mape_w2l_fast(skb, state->in, __func__))
917 return NF_STOLEN;
918 else
919 return NF_ACCEPT;
920 }
developerf4c370a2022-10-08 17:01:19 +0800921#endif
developerfd40db22021-04-29 10:08:25 +0800922 return NF_ACCEPT;
923drop:
developer577ad2f2022-11-28 10:33:36 +0800924 if (skb)
925 printk_ratelimited(KERN_WARNING
926 "%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x,\n"
927 "sport=0x%x, reason=0x%x, alg=0x%x)\n",
928 __func__, state->in->name, skb_hnat_iface(skb),
929 HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
930 skb_hnat_sport(skb), skb_hnat_reason(skb),
931 skb_hnat_alg(skb));
developerfd40db22021-04-29 10:08:25 +0800932
933 return NF_DROP;
934}
935
936static unsigned int hnat_ipv6_get_nexthop(struct sk_buff *skb,
937 const struct net_device *out,
938 struct flow_offload_hw_path *hw_path)
939{
940 const struct in6_addr *ipv6_nexthop;
941 struct neighbour *neigh = NULL;
942 struct dst_entry *dst = skb_dst(skb);
943 struct ethhdr *eth;
944
945 if (hw_path->flags & FLOW_OFFLOAD_PATH_PPPOE) {
946 memcpy(eth_hdr(skb)->h_source, hw_path->eth_src, ETH_ALEN);
947 memcpy(eth_hdr(skb)->h_dest, hw_path->eth_dest, ETH_ALEN);
948 return 0;
949 }
950
951 rcu_read_lock_bh();
952 ipv6_nexthop =
953 rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr);
954 neigh = __ipv6_neigh_lookup_noref(dst->dev, ipv6_nexthop);
955 if (unlikely(!neigh)) {
956 dev_notice(hnat_priv->dev, "%s:No neigh (daddr=%pI6)\n", __func__,
957 &ipv6_hdr(skb)->daddr);
958 rcu_read_unlock_bh();
959 return -1;
960 }
961
962 /* why do we get all zero ethernet address ? */
963 if (!is_valid_ether_addr(neigh->ha)) {
964 rcu_read_unlock_bh();
965 return -1;
966 }
967
968 if (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPIP) {
969 /*copy ether type for DS-Lite and MapE */
970 eth = (struct ethhdr *)(skb->data - ETH_HLEN);
971 eth->h_proto = skb->protocol;
972 } else {
973 eth = eth_hdr(skb);
974 }
975
976 ether_addr_copy(eth->h_dest, neigh->ha);
977 ether_addr_copy(eth->h_source, out->dev_addr);
978
979 rcu_read_unlock_bh();
980
981 return 0;
982}
983
984static unsigned int hnat_ipv4_get_nexthop(struct sk_buff *skb,
985 const struct net_device *out,
986 struct flow_offload_hw_path *hw_path)
987{
988 u32 nexthop;
989 struct neighbour *neigh;
990 struct dst_entry *dst = skb_dst(skb);
991 struct rtable *rt = (struct rtable *)dst;
992 struct net_device *dev = (__force struct net_device *)out;
993
994 if (hw_path->flags & FLOW_OFFLOAD_PATH_PPPOE) {
995 memcpy(eth_hdr(skb)->h_source, hw_path->eth_src, ETH_ALEN);
996 memcpy(eth_hdr(skb)->h_dest, hw_path->eth_dest, ETH_ALEN);
997 return 0;
998 }
999
1000 rcu_read_lock_bh();
1001 nexthop = (__force u32)rt_nexthop(rt, ip_hdr(skb)->daddr);
1002 neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
1003 if (unlikely(!neigh)) {
1004 dev_notice(hnat_priv->dev, "%s:No neigh (daddr=%pI4)\n", __func__,
1005 &ip_hdr(skb)->daddr);
1006 rcu_read_unlock_bh();
1007 return -1;
1008 }
1009
1010 /* why do we get all zero ethernet address ? */
1011 if (!is_valid_ether_addr(neigh->ha)) {
1012 rcu_read_unlock_bh();
1013 return -1;
1014 }
1015
1016 memcpy(eth_hdr(skb)->h_dest, neigh->ha, ETH_ALEN);
1017 memcpy(eth_hdr(skb)->h_source, out->dev_addr, ETH_ALEN);
1018
1019 rcu_read_unlock_bh();
1020
1021 return 0;
1022}
1023
1024static u16 ppe_get_chkbase(struct iphdr *iph)
1025{
1026 u16 org_chksum = ntohs(iph->check);
1027 u16 org_tot_len = ntohs(iph->tot_len);
1028 u16 org_id = ntohs(iph->id);
1029 u16 chksum_tmp, tot_len_tmp, id_tmp;
1030 u32 tmp = 0;
1031 u16 chksum_base = 0;
1032
1033 chksum_tmp = ~(org_chksum);
1034 tot_len_tmp = ~(org_tot_len);
1035 id_tmp = ~(org_id);
1036 tmp = chksum_tmp + tot_len_tmp + id_tmp;
1037 tmp = ((tmp >> 16) & 0x7) + (tmp & 0xFFFF);
1038 tmp = ((tmp >> 16) & 0x7) + (tmp & 0xFFFF);
1039 chksum_base = tmp & 0xFFFF;
1040
1041 return chksum_base;
1042}
1043
1044struct foe_entry ppe_fill_L2_info(struct ethhdr *eth, struct foe_entry entry,
1045 struct flow_offload_hw_path *hw_path)
1046{
developer5ffc5f12022-10-25 18:51:46 +08001047 switch ((int)entry.bfib1.pkt_type) {
developerfd40db22021-04-29 10:08:25 +08001048 case IPV4_HNAPT:
1049 case IPV4_HNAT:
1050 entry.ipv4_hnapt.dmac_hi = swab32(*((u32 *)eth->h_dest));
1051 entry.ipv4_hnapt.dmac_lo = swab16(*((u16 *)&eth->h_dest[4]));
1052 entry.ipv4_hnapt.smac_hi = swab32(*((u32 *)eth->h_source));
1053 entry.ipv4_hnapt.smac_lo = swab16(*((u16 *)&eth->h_source[4]));
1054 entry.ipv4_hnapt.pppoe_id = hw_path->pppoe_sid;
1055 break;
1056 case IPV4_DSLITE:
1057 case IPV4_MAP_E:
1058 case IPV6_6RD:
1059 case IPV6_5T_ROUTE:
1060 case IPV6_3T_ROUTE:
developer5ffc5f12022-10-25 18:51:46 +08001061 case IPV6_HNAPT:
1062 case IPV6_HNAT:
developerfd40db22021-04-29 10:08:25 +08001063 entry.ipv6_5t_route.dmac_hi = swab32(*((u32 *)eth->h_dest));
1064 entry.ipv6_5t_route.dmac_lo = swab16(*((u16 *)&eth->h_dest[4]));
1065 entry.ipv6_5t_route.smac_hi = swab32(*((u32 *)eth->h_source));
1066 entry.ipv6_5t_route.smac_lo =
1067 swab16(*((u16 *)&eth->h_source[4]));
1068 entry.ipv6_5t_route.pppoe_id = hw_path->pppoe_sid;
1069 break;
1070 }
1071 return entry;
1072}
1073
1074struct foe_entry ppe_fill_info_blk(struct ethhdr *eth, struct foe_entry entry,
1075 struct flow_offload_hw_path *hw_path)
1076{
1077 entry.bfib1.psn = (hw_path->flags & FLOW_OFFLOAD_PATH_PPPOE) ? 1 : 0;
1078 entry.bfib1.vlan_layer += (hw_path->flags & FLOW_OFFLOAD_PATH_VLAN) ? 1 : 0;
1079 entry.bfib1.vpm = (entry.bfib1.vlan_layer) ? 1 : 0;
developerfd40db22021-04-29 10:08:25 +08001080 entry.bfib1.cah = 1;
developer4164cfe2022-12-01 11:27:41 +08001081 entry.bfib1.time_stamp = (hnat_priv->data->version == MTK_HNAT_V2 ||
1082 hnat_priv->data->version == MTK_HNAT_V3) ?
developerfd40db22021-04-29 10:08:25 +08001083 readl(hnat_priv->fe_base + 0x0010) & (0xFF) :
1084 readl(hnat_priv->fe_base + 0x0010) & (0x7FFF);
1085
developer5ffc5f12022-10-25 18:51:46 +08001086 switch ((int)entry.bfib1.pkt_type) {
developerfd40db22021-04-29 10:08:25 +08001087 case IPV4_HNAPT:
1088 case IPV4_HNAT:
developer8116b0a2021-08-23 18:07:20 +08001089 if (hnat_priv->data->mcast &&
1090 is_multicast_ether_addr(&eth->h_dest[0])) {
developerfd40db22021-04-29 10:08:25 +08001091 entry.ipv4_hnapt.iblk2.mcast = 1;
developer4164cfe2022-12-01 11:27:41 +08001092 if (hnat_priv->data->version == MTK_HNAT_V1_3) {
developerfd40db22021-04-29 10:08:25 +08001093 entry.bfib1.sta = 1;
1094 entry.ipv4_hnapt.m_timestamp = foe_timestamp(hnat_priv);
1095 }
1096 } else {
1097 entry.ipv4_hnapt.iblk2.mcast = 0;
1098 }
1099
1100 entry.ipv4_hnapt.iblk2.port_ag =
developer4164cfe2022-12-01 11:27:41 +08001101 (hnat_priv->data->version == MTK_HNAT_V2 ||
1102 hnat_priv->data->version == MTK_HNAT_V3) ? 0xf : 0x3f;
developerfd40db22021-04-29 10:08:25 +08001103 break;
1104 case IPV4_DSLITE:
1105 case IPV4_MAP_E:
1106 case IPV6_6RD:
1107 case IPV6_5T_ROUTE:
1108 case IPV6_3T_ROUTE:
developer5ffc5f12022-10-25 18:51:46 +08001109 case IPV6_HNAPT:
1110 case IPV6_HNAT:
developer8116b0a2021-08-23 18:07:20 +08001111 if (hnat_priv->data->mcast &&
1112 is_multicast_ether_addr(&eth->h_dest[0])) {
developerfd40db22021-04-29 10:08:25 +08001113 entry.ipv6_5t_route.iblk2.mcast = 1;
developer4164cfe2022-12-01 11:27:41 +08001114 if (hnat_priv->data->version == MTK_HNAT_V1_3) {
developerfd40db22021-04-29 10:08:25 +08001115 entry.bfib1.sta = 1;
1116 entry.ipv4_hnapt.m_timestamp = foe_timestamp(hnat_priv);
1117 }
1118 } else {
1119 entry.ipv6_5t_route.iblk2.mcast = 0;
1120 }
1121
1122 entry.ipv6_5t_route.iblk2.port_ag =
developer4164cfe2022-12-01 11:27:41 +08001123 (hnat_priv->data->version == MTK_HNAT_V2 ||
1124 hnat_priv->data->version == MTK_HNAT_V3) ? 0xf : 0x3f;
developerfd40db22021-04-29 10:08:25 +08001125 break;
1126 }
1127 return entry;
1128}
1129
developerfd40db22021-04-29 10:08:25 +08001130static unsigned int skb_to_hnat_info(struct sk_buff *skb,
1131 const struct net_device *dev,
1132 struct foe_entry *foe,
1133 struct flow_offload_hw_path *hw_path)
1134{
1135 struct foe_entry entry = { 0 };
1136 int whnat = IS_WHNAT(dev);
1137 struct ethhdr *eth;
1138 struct iphdr *iph;
1139 struct ipv6hdr *ip6h;
1140 struct tcpudphdr _ports;
1141 const struct tcpudphdr *pptr;
developer5ffc5f12022-10-25 18:51:46 +08001142 struct nf_conn *ct;
1143 enum ip_conntrack_info ctinfo;
developerfd40db22021-04-29 10:08:25 +08001144 u32 gmac = NR_DISCARD;
1145 int udp = 0;
1146 u32 qid = 0;
developeraf07fad2021-11-19 17:53:42 +08001147 u32 port_id = 0;
developerfd40db22021-04-29 10:08:25 +08001148 int mape = 0;
1149
developer5ffc5f12022-10-25 18:51:46 +08001150 ct = nf_ct_get(skb, &ctinfo);
1151
developerfd40db22021-04-29 10:08:25 +08001152 if (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPIP)
1153 /* point to ethernet header for DS-Lite and MapE */
1154 eth = (struct ethhdr *)(skb->data - ETH_HLEN);
1155 else
1156 eth = eth_hdr(skb);
developer8116b0a2021-08-23 18:07:20 +08001157
1158 /*do not bind multicast if PPE mcast not enable*/
1159 if (!hnat_priv->data->mcast && is_multicast_ether_addr(eth->h_dest))
1160 return 0;
developerfd40db22021-04-29 10:08:25 +08001161
1162 entry.bfib1.pkt_type = foe->udib1.pkt_type; /* Get packte type state*/
developerf94d8862022-03-29 10:11:17 +08001163 entry.bfib1.state = foe->udib1.state;
1164
developerd35bbcc2022-09-28 22:46:01 +08001165#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
developerfd40db22021-04-29 10:08:25 +08001166 entry.bfib1.sp = foe->udib1.sp;
1167#endif
1168
1169 switch (ntohs(eth->h_proto)) {
1170 case ETH_P_IP:
1171 iph = ip_hdr(skb);
1172 switch (iph->protocol) {
1173 case IPPROTO_UDP:
1174 udp = 1;
1175 /* fallthrough */
1176 case IPPROTO_TCP:
1177 entry.ipv4_hnapt.etype = htons(ETH_P_IP);
1178
1179 /* DS-Lite WAN->LAN */
1180 if (entry.ipv4_hnapt.bfib1.pkt_type == IPV4_DSLITE ||
1181 entry.ipv4_hnapt.bfib1.pkt_type == IPV4_MAP_E) {
1182 entry.ipv4_dslite.sip = foe->ipv4_dslite.sip;
1183 entry.ipv4_dslite.dip = foe->ipv4_dslite.dip;
1184 entry.ipv4_dslite.sport =
1185 foe->ipv4_dslite.sport;
1186 entry.ipv4_dslite.dport =
1187 foe->ipv4_dslite.dport;
1188
developerd35bbcc2022-09-28 22:46:01 +08001189#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
developerfd40db22021-04-29 10:08:25 +08001190 if (entry.bfib1.pkt_type == IPV4_MAP_E) {
1191 pptr = skb_header_pointer(skb,
1192 iph->ihl * 4,
1193 sizeof(_ports),
1194 &_ports);
developer4c32b7a2021-11-13 16:46:43 +08001195 if (unlikely(!pptr))
1196 return -1;
developerfd40db22021-04-29 10:08:25 +08001197
developerd35bbcc2022-09-28 22:46:01 +08001198 entry.ipv4_mape.new_sip =
developerfd40db22021-04-29 10:08:25 +08001199 ntohl(iph->saddr);
developerd35bbcc2022-09-28 22:46:01 +08001200 entry.ipv4_mape.new_dip =
developerfd40db22021-04-29 10:08:25 +08001201 ntohl(iph->daddr);
developerd35bbcc2022-09-28 22:46:01 +08001202 entry.ipv4_mape.new_sport =
developerfd40db22021-04-29 10:08:25 +08001203 ntohs(pptr->src);
developerd35bbcc2022-09-28 22:46:01 +08001204 entry.ipv4_mape.new_dport =
developerfd40db22021-04-29 10:08:25 +08001205 ntohs(pptr->dst);
1206 }
1207#endif
1208
1209 entry.ipv4_dslite.tunnel_sipv6_0 =
1210 foe->ipv4_dslite.tunnel_sipv6_0;
1211 entry.ipv4_dslite.tunnel_sipv6_1 =
1212 foe->ipv4_dslite.tunnel_sipv6_1;
1213 entry.ipv4_dslite.tunnel_sipv6_2 =
1214 foe->ipv4_dslite.tunnel_sipv6_2;
1215 entry.ipv4_dslite.tunnel_sipv6_3 =
1216 foe->ipv4_dslite.tunnel_sipv6_3;
1217
1218 entry.ipv4_dslite.tunnel_dipv6_0 =
1219 foe->ipv4_dslite.tunnel_dipv6_0;
1220 entry.ipv4_dslite.tunnel_dipv6_1 =
1221 foe->ipv4_dslite.tunnel_dipv6_1;
1222 entry.ipv4_dslite.tunnel_dipv6_2 =
1223 foe->ipv4_dslite.tunnel_dipv6_2;
1224 entry.ipv4_dslite.tunnel_dipv6_3 =
1225 foe->ipv4_dslite.tunnel_dipv6_3;
1226
1227 entry.ipv4_dslite.bfib1.rmt = 1;
1228 entry.ipv4_dslite.iblk2.dscp = iph->tos;
1229 entry.ipv4_dslite.vlan1 = hw_path->vlan_id;
1230 if (hnat_priv->data->per_flow_accounting)
1231 entry.ipv4_dslite.iblk2.mibf = 1;
1232
1233 } else {
1234 entry.ipv4_hnapt.iblk2.dscp = iph->tos;
1235 if (hnat_priv->data->per_flow_accounting)
1236 entry.ipv4_hnapt.iblk2.mibf = 1;
1237
1238 entry.ipv4_hnapt.vlan1 = hw_path->vlan_id;
1239
developerdfc8ef52022-12-06 14:00:09 +08001240 if (skb_vlan_tag_present(skb)) {
developerfd40db22021-04-29 10:08:25 +08001241 entry.bfib1.vlan_layer += 1;
1242
1243 if (entry.ipv4_hnapt.vlan1)
developerdfc8ef52022-12-06 14:00:09 +08001244 entry.ipv4_hnapt.vlan2 =
1245 skb->vlan_tci;
developerfd40db22021-04-29 10:08:25 +08001246 else
developerdfc8ef52022-12-06 14:00:09 +08001247 entry.ipv4_hnapt.vlan1 =
1248 skb->vlan_tci;
1249 }
developerfd40db22021-04-29 10:08:25 +08001250
1251 entry.ipv4_hnapt.sip = foe->ipv4_hnapt.sip;
1252 entry.ipv4_hnapt.dip = foe->ipv4_hnapt.dip;
1253 entry.ipv4_hnapt.sport = foe->ipv4_hnapt.sport;
1254 entry.ipv4_hnapt.dport = foe->ipv4_hnapt.dport;
1255
1256 entry.ipv4_hnapt.new_sip = ntohl(iph->saddr);
1257 entry.ipv4_hnapt.new_dip = ntohl(iph->daddr);
1258 }
1259
1260 entry.ipv4_hnapt.bfib1.udp = udp;
1261 if (IS_IPV4_HNAPT(foe)) {
1262 pptr = skb_header_pointer(skb, iph->ihl * 4,
1263 sizeof(_ports),
1264 &_ports);
developer4c32b7a2021-11-13 16:46:43 +08001265 if (unlikely(!pptr))
1266 return -1;
1267
developerfd40db22021-04-29 10:08:25 +08001268 entry.ipv4_hnapt.new_sport = ntohs(pptr->src);
1269 entry.ipv4_hnapt.new_dport = ntohs(pptr->dst);
1270 }
1271
1272 break;
1273
1274 default:
1275 return -1;
1276 }
1277 trace_printk(
1278 "[%s]skb->head=%p, skb->data=%p,ip_hdr=%p, skb->len=%d, skb->data_len=%d\n",
1279 __func__, skb->head, skb->data, iph, skb->len,
1280 skb->data_len);
1281 break;
1282
1283 case ETH_P_IPV6:
1284 ip6h = ipv6_hdr(skb);
1285 switch (ip6h->nexthdr) {
1286 case NEXTHDR_UDP:
1287 udp = 1;
1288 /* fallthrough */
1289 case NEXTHDR_TCP: /* IPv6-5T or IPv6-3T */
1290 entry.ipv6_5t_route.etype = htons(ETH_P_IPV6);
1291
1292 entry.ipv6_5t_route.vlan1 = hw_path->vlan_id;
1293
developerdfc8ef52022-12-06 14:00:09 +08001294 if (skb_vlan_tag_present(skb)) {
developerfd40db22021-04-29 10:08:25 +08001295 entry.bfib1.vlan_layer += 1;
1296
1297 if (entry.ipv6_5t_route.vlan1)
developerdfc8ef52022-12-06 14:00:09 +08001298 entry.ipv6_5t_route.vlan2 =
1299 skb->vlan_tci;
developerfd40db22021-04-29 10:08:25 +08001300 else
developerdfc8ef52022-12-06 14:00:09 +08001301 entry.ipv6_5t_route.vlan1 =
1302 skb->vlan_tci;
developerfd40db22021-04-29 10:08:25 +08001303 }
1304
1305 if (hnat_priv->data->per_flow_accounting)
1306 entry.ipv6_5t_route.iblk2.mibf = 1;
1307 entry.ipv6_5t_route.bfib1.udp = udp;
1308
1309 if (IS_IPV6_6RD(foe)) {
1310 entry.ipv6_5t_route.bfib1.rmt = 1;
1311 entry.ipv6_6rd.tunnel_sipv4 =
1312 foe->ipv6_6rd.tunnel_sipv4;
1313 entry.ipv6_6rd.tunnel_dipv4 =
1314 foe->ipv6_6rd.tunnel_dipv4;
1315 }
1316
1317 entry.ipv6_3t_route.ipv6_sip0 =
1318 foe->ipv6_3t_route.ipv6_sip0;
1319 entry.ipv6_3t_route.ipv6_sip1 =
1320 foe->ipv6_3t_route.ipv6_sip1;
1321 entry.ipv6_3t_route.ipv6_sip2 =
1322 foe->ipv6_3t_route.ipv6_sip2;
1323 entry.ipv6_3t_route.ipv6_sip3 =
1324 foe->ipv6_3t_route.ipv6_sip3;
1325
1326 entry.ipv6_3t_route.ipv6_dip0 =
1327 foe->ipv6_3t_route.ipv6_dip0;
1328 entry.ipv6_3t_route.ipv6_dip1 =
1329 foe->ipv6_3t_route.ipv6_dip1;
1330 entry.ipv6_3t_route.ipv6_dip2 =
1331 foe->ipv6_3t_route.ipv6_dip2;
1332 entry.ipv6_3t_route.ipv6_dip3 =
1333 foe->ipv6_3t_route.ipv6_dip3;
1334
developer729f0272021-06-09 17:28:38 +08001335 if (IS_IPV6_3T_ROUTE(foe)) {
1336 entry.ipv6_3t_route.prot =
1337 foe->ipv6_3t_route.prot;
1338 entry.ipv6_3t_route.hph =
1339 foe->ipv6_3t_route.hph;
1340 }
1341
developerfd40db22021-04-29 10:08:25 +08001342 if (IS_IPV6_5T_ROUTE(foe) || IS_IPV6_6RD(foe)) {
1343 entry.ipv6_5t_route.sport =
1344 foe->ipv6_5t_route.sport;
1345 entry.ipv6_5t_route.dport =
1346 foe->ipv6_5t_route.dport;
1347 }
developer5ffc5f12022-10-25 18:51:46 +08001348
1349#if defined(CONFIG_MEDIATEK_NETSYS_V3)
1350 if (ct && (ct->status & IPS_SRC_NAT)) {
1351 entry.bfib1.pkt_type = IPV6_HNAPT;
1352
1353 if (IS_WAN(dev) || IS_DSA_WAN(dev)) {
1354 entry.ipv6_hnapt.eg_ipv6_dir =
1355 IPV6_SNAT;
1356 entry.ipv6_hnapt.new_ipv6_ip0 =
1357 ntohl(ip6h->saddr.s6_addr32[0]);
1358 entry.ipv6_hnapt.new_ipv6_ip1 =
1359 ntohl(ip6h->saddr.s6_addr32[1]);
1360 entry.ipv6_hnapt.new_ipv6_ip2 =
1361 ntohl(ip6h->saddr.s6_addr32[2]);
1362 entry.ipv6_hnapt.new_ipv6_ip3 =
1363 ntohl(ip6h->saddr.s6_addr32[3]);
1364 } else {
1365 entry.ipv6_hnapt.eg_ipv6_dir =
1366 IPV6_DNAT;
1367 entry.ipv6_hnapt.new_ipv6_ip0 =
1368 ntohl(ip6h->daddr.s6_addr32[0]);
1369 entry.ipv6_hnapt.new_ipv6_ip1 =
1370 ntohl(ip6h->daddr.s6_addr32[1]);
1371 entry.ipv6_hnapt.new_ipv6_ip2 =
1372 ntohl(ip6h->daddr.s6_addr32[2]);
1373 entry.ipv6_hnapt.new_ipv6_ip3 =
1374 ntohl(ip6h->daddr.s6_addr32[3]);
1375 }
1376
1377 pptr = skb_header_pointer(skb, IPV6_HDR_LEN,
1378 sizeof(_ports),
1379 &_ports);
1380 if (unlikely(!pptr))
1381 return -1;
1382
1383 entry.ipv6_hnapt.new_sport = ntohs(pptr->src);
1384 entry.ipv6_hnapt.new_dport = ntohs(pptr->dst);
1385 }
1386#endif
1387
developerfd40db22021-04-29 10:08:25 +08001388 entry.ipv6_5t_route.iblk2.dscp =
1389 (ip6h->priority << 4 |
1390 (ip6h->flow_lbl[0] >> 4));
1391 break;
1392
1393 case NEXTHDR_IPIP:
1394 if ((!mape_toggle &&
1395 entry.bfib1.pkt_type == IPV4_DSLITE) ||
1396 (mape_toggle &&
1397 entry.bfib1.pkt_type == IPV4_MAP_E)) {
1398 /* DS-Lite LAN->WAN */
1399 entry.ipv4_dslite.bfib1.udp =
1400 foe->ipv4_dslite.bfib1.udp;
1401 entry.ipv4_dslite.sip = foe->ipv4_dslite.sip;
1402 entry.ipv4_dslite.dip = foe->ipv4_dslite.dip;
1403 entry.ipv4_dslite.sport =
1404 foe->ipv4_dslite.sport;
1405 entry.ipv4_dslite.dport =
1406 foe->ipv4_dslite.dport;
1407
1408 entry.ipv4_dslite.tunnel_sipv6_0 =
1409 ntohl(ip6h->saddr.s6_addr32[0]);
1410 entry.ipv4_dslite.tunnel_sipv6_1 =
1411 ntohl(ip6h->saddr.s6_addr32[1]);
1412 entry.ipv4_dslite.tunnel_sipv6_2 =
1413 ntohl(ip6h->saddr.s6_addr32[2]);
1414 entry.ipv4_dslite.tunnel_sipv6_3 =
1415 ntohl(ip6h->saddr.s6_addr32[3]);
1416
1417 entry.ipv4_dslite.tunnel_dipv6_0 =
1418 ntohl(ip6h->daddr.s6_addr32[0]);
1419 entry.ipv4_dslite.tunnel_dipv6_1 =
1420 ntohl(ip6h->daddr.s6_addr32[1]);
1421 entry.ipv4_dslite.tunnel_dipv6_2 =
1422 ntohl(ip6h->daddr.s6_addr32[2]);
1423 entry.ipv4_dslite.tunnel_dipv6_3 =
1424 ntohl(ip6h->daddr.s6_addr32[3]);
1425
1426 ppe_fill_flow_lbl(&entry, ip6h);
1427
1428 entry.ipv4_dslite.priority = ip6h->priority;
1429 entry.ipv4_dslite.hop_limit = ip6h->hop_limit;
1430 entry.ipv4_dslite.vlan1 = hw_path->vlan_id;
1431 if (hnat_priv->data->per_flow_accounting)
1432 entry.ipv4_dslite.iblk2.mibf = 1;
developer25fc8c02022-05-06 16:24:02 +08001433 /* Map-E LAN->WAN record inner IPv4 header info. */
developer8c707df2022-10-24 14:09:00 +08001434#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
developer25fc8c02022-05-06 16:24:02 +08001435 if (mape_toggle) {
1436 entry.ipv4_dslite.iblk2.dscp = foe->ipv4_dslite.iblk2.dscp;
developerd35bbcc2022-09-28 22:46:01 +08001437 entry.ipv4_mape.new_sip = foe->ipv4_mape.new_sip;
1438 entry.ipv4_mape.new_dip = foe->ipv4_mape.new_dip;
1439 entry.ipv4_mape.new_sport = foe->ipv4_mape.new_sport;
1440 entry.ipv4_mape.new_dport = foe->ipv4_mape.new_dport;
developer25fc8c02022-05-06 16:24:02 +08001441 }
1442#endif
developerfd40db22021-04-29 10:08:25 +08001443 } else if (mape_toggle &&
1444 entry.bfib1.pkt_type == IPV4_HNAPT) {
1445 /* MapE LAN -> WAN */
1446 mape = 1;
1447 entry.ipv4_hnapt.iblk2.dscp =
1448 foe->ipv4_hnapt.iblk2.dscp;
1449 if (hnat_priv->data->per_flow_accounting)
1450 entry.ipv4_hnapt.iblk2.mibf = 1;
1451
developerbb816412021-06-11 15:43:44 +08001452 if (IS_GMAC1_MODE)
1453 entry.ipv4_hnapt.vlan1 = 1;
1454 else
1455 entry.ipv4_hnapt.vlan1 = hw_path->vlan_id;
developerfd40db22021-04-29 10:08:25 +08001456
1457 entry.ipv4_hnapt.sip = foe->ipv4_hnapt.sip;
1458 entry.ipv4_hnapt.dip = foe->ipv4_hnapt.dip;
1459 entry.ipv4_hnapt.sport = foe->ipv4_hnapt.sport;
1460 entry.ipv4_hnapt.dport = foe->ipv4_hnapt.dport;
1461
1462 entry.ipv4_hnapt.new_sip =
1463 foe->ipv4_hnapt.new_sip;
1464 entry.ipv4_hnapt.new_dip =
1465 foe->ipv4_hnapt.new_dip;
1466 entry.ipv4_hnapt.etype = htons(ETH_P_IP);
1467
developer34028fb2022-01-11 13:51:29 +08001468 if (IS_HQOS_MODE) {
developeraf07fad2021-11-19 17:53:42 +08001469 entry.ipv4_hnapt.iblk2.qid =
developer4164cfe2022-12-01 11:27:41 +08001470 (hnat_priv->data->version ==
1471 MTK_HNAT_V2 ||
1472 hnat_priv->data->version ==
1473 MTK_HNAT_V3) ?
developeraf07fad2021-11-19 17:53:42 +08001474 skb->mark & 0x7f : skb->mark & 0xf;
developerd35bbcc2022-09-28 22:46:01 +08001475#if defined(CONFIG_MEDIATEK_NETSYS_V3)
developer934756a2022-11-18 14:51:34 +08001476 if ((IS_HQOS_UL_MODE && IS_WAN(dev)) ||
developer493adc32022-11-29 22:34:18 +08001477 (IS_HQOS_DL_MODE &&
1478 IS_LAN_GRP(dev)) ||
developer934756a2022-11-18 14:51:34 +08001479 (IS_PPPQ_MODE &&
1480 IS_PPPQ_PATH(dev, skb)))
developer47545a32022-11-15 16:06:58 +08001481 entry.ipv4_hnapt.tport_id = 1;
1482 else
1483 entry.ipv4_hnapt.tport_id = 0;
developerd35bbcc2022-09-28 22:46:01 +08001484#else
developeraf07fad2021-11-19 17:53:42 +08001485 entry.ipv4_hnapt.iblk2.fqos = 1;
developerd35bbcc2022-09-28 22:46:01 +08001486#endif
developeraf07fad2021-11-19 17:53:42 +08001487 }
developerfd40db22021-04-29 10:08:25 +08001488
1489 entry.ipv4_hnapt.bfib1.udp =
1490 foe->ipv4_hnapt.bfib1.udp;
1491
1492 entry.ipv4_hnapt.new_sport =
1493 foe->ipv4_hnapt.new_sport;
1494 entry.ipv4_hnapt.new_dport =
1495 foe->ipv4_hnapt.new_dport;
1496 mape_l2w_v6h = *ip6h;
1497 }
1498 break;
1499
1500 default:
1501 return -1;
1502 }
1503
1504 trace_printk(
1505 "[%s]skb->head=%p, skb->data=%p,ipv6_hdr=%p, skb->len=%d, skb->data_len=%d\n",
1506 __func__, skb->head, skb->data, ip6h, skb->len,
1507 skb->data_len);
1508 break;
1509
1510 default:
developerfd40db22021-04-29 10:08:25 +08001511 iph = ip_hdr(skb);
1512 switch (entry.bfib1.pkt_type) {
1513 case IPV6_6RD: /* 6RD LAN->WAN */
1514 entry.ipv6_6rd.ipv6_sip0 = foe->ipv6_6rd.ipv6_sip0;
1515 entry.ipv6_6rd.ipv6_sip1 = foe->ipv6_6rd.ipv6_sip1;
1516 entry.ipv6_6rd.ipv6_sip2 = foe->ipv6_6rd.ipv6_sip2;
1517 entry.ipv6_6rd.ipv6_sip3 = foe->ipv6_6rd.ipv6_sip3;
1518
1519 entry.ipv6_6rd.ipv6_dip0 = foe->ipv6_6rd.ipv6_dip0;
1520 entry.ipv6_6rd.ipv6_dip1 = foe->ipv6_6rd.ipv6_dip1;
1521 entry.ipv6_6rd.ipv6_dip2 = foe->ipv6_6rd.ipv6_dip2;
1522 entry.ipv6_6rd.ipv6_dip3 = foe->ipv6_6rd.ipv6_dip3;
1523
1524 entry.ipv6_6rd.sport = foe->ipv6_6rd.sport;
1525 entry.ipv6_6rd.dport = foe->ipv6_6rd.dport;
1526 entry.ipv6_6rd.tunnel_sipv4 = ntohl(iph->saddr);
1527 entry.ipv6_6rd.tunnel_dipv4 = ntohl(iph->daddr);
1528 entry.ipv6_6rd.hdr_chksum = ppe_get_chkbase(iph);
1529 entry.ipv6_6rd.flag = (ntohs(iph->frag_off) >> 13);
1530 entry.ipv6_6rd.ttl = iph->ttl;
1531 entry.ipv6_6rd.dscp = iph->tos;
1532 entry.ipv6_6rd.per_flow_6rd_id = 1;
1533 entry.ipv6_6rd.vlan1 = hw_path->vlan_id;
1534 if (hnat_priv->data->per_flow_accounting)
1535 entry.ipv6_6rd.iblk2.mibf = 1;
1536 break;
1537
1538 default:
1539 return -1;
1540 }
1541 }
1542
1543 /* Fill Layer2 Info.*/
1544 entry = ppe_fill_L2_info(eth, entry, hw_path);
1545
1546 /* Fill Info Blk*/
1547 entry = ppe_fill_info_blk(eth, entry, hw_path);
1548
1549 if (IS_LAN(dev)) {
1550 if (IS_DSA_LAN(dev))
developeraf07fad2021-11-19 17:53:42 +08001551 port_id = hnat_dsa_fill_stag(dev, &entry, hw_path,
1552 ntohs(eth->h_proto),
1553 mape);
developerfd40db22021-04-29 10:08:25 +08001554
1555 if (IS_BOND_MODE)
1556 gmac = ((skb_hnat_entry(skb) >> 1) % hnat_priv->gmac_num) ?
1557 NR_GMAC2_PORT : NR_GMAC1_PORT;
1558 else
1559 gmac = NR_GMAC1_PORT;
developerd35bbcc2022-09-28 22:46:01 +08001560 } else if (IS_LAN2(dev)) {
1561 gmac = NR_GMAC3_PORT;
developerfd40db22021-04-29 10:08:25 +08001562 } else if (IS_WAN(dev)) {
1563 if (IS_DSA_WAN(dev))
developeraf07fad2021-11-19 17:53:42 +08001564 port_id = hnat_dsa_fill_stag(dev,&entry, hw_path,
1565 ntohs(eth->h_proto),
1566 mape);
developerfd40db22021-04-29 10:08:25 +08001567 if (mape_toggle && mape == 1) {
1568 gmac = NR_PDMA_PORT;
1569 /* Set act_dp = wan_dev */
1570 entry.ipv4_hnapt.act_dp = dev->ifindex;
1571 } else {
1572 gmac = (IS_GMAC1_MODE) ? NR_GMAC1_PORT : NR_GMAC2_PORT;
1573 }
developerd35bbcc2022-09-28 22:46:01 +08001574 } else if (IS_EXT(dev) && (FROM_GE_PPD(skb) || FROM_GE_LAN_GRP(skb) ||
developer99506e52021-06-30 22:03:02 +08001575 FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb) || FROM_WED(skb))) {
developerfd40db22021-04-29 10:08:25 +08001576 if (!hnat_priv->data->whnat && IS_GMAC1_MODE) {
1577 entry.bfib1.vpm = 1;
1578 entry.bfib1.vlan_layer = 1;
1579
1580 if (FROM_GE_LAN(skb))
1581 entry.ipv4_hnapt.vlan1 = 1;
1582 else if (FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb))
1583 entry.ipv4_hnapt.vlan1 = 2;
1584 }
1585
1586 trace_printk("learn of lan or wan(iif=%x) --> %s(ext)\n",
1587 skb_hnat_iface(skb), dev->name);
1588 /* To CPU then stolen by pre-routing hant hook of LAN/WAN
1589 * Current setting is PDMA RX.
1590 */
1591 gmac = NR_PDMA_PORT;
1592 if (IS_IPV4_GRP(foe))
1593 entry.ipv4_hnapt.act_dp = dev->ifindex;
1594 else
1595 entry.ipv6_5t_route.act_dp = dev->ifindex;
1596 } else {
1597 printk_ratelimited(KERN_WARNING
1598 "Unknown case of dp, iif=%x --> %s\n",
1599 skb_hnat_iface(skb), dev->name);
1600
1601 return 0;
1602 }
1603
developerafff5662022-06-29 10:09:56 +08001604 if (IS_HQOS_MODE || skb->mark >= MAX_PPPQ_PORT_NUM)
developeraf07fad2021-11-19 17:53:42 +08001605 qid = skb->mark & (MTK_QDMA_TX_MASK);
developer934756a2022-11-18 14:51:34 +08001606 else if (IS_PPPQ_MODE && IS_PPPQ_PATH(dev, skb))
developeraf07fad2021-11-19 17:53:42 +08001607 qid = port_id & MTK_QDMA_TX_MASK;
1608 else
1609 qid = 0;
developerfd40db22021-04-29 10:08:25 +08001610
1611 if (IS_IPV4_GRP(foe)) {
1612 entry.ipv4_hnapt.iblk2.dp = gmac;
1613 entry.ipv4_hnapt.iblk2.port_mg =
developer4164cfe2022-12-01 11:27:41 +08001614 (hnat_priv->data->version == MTK_HNAT_V1_1) ? 0x3f : 0;
developer24948202021-11-24 17:38:27 +08001615
developeraf07fad2021-11-19 17:53:42 +08001616 if (qos_toggle) {
developer4164cfe2022-12-01 11:27:41 +08001617 if (hnat_priv->data->version == MTK_HNAT_V2 ||
1618 hnat_priv->data->version == MTK_HNAT_V3) {
developeraf07fad2021-11-19 17:53:42 +08001619 entry.ipv4_hnapt.iblk2.qid = qid & 0x7f;
1620 } else {
1621 /* qid[5:0]= port_mg[1:0]+ qid[3:0] */
1622 entry.ipv4_hnapt.iblk2.qid = qid & 0xf;
developer4164cfe2022-12-01 11:27:41 +08001623 if (hnat_priv->data->version != MTK_HNAT_V1_1)
developeraf07fad2021-11-19 17:53:42 +08001624 entry.ipv4_hnapt.iblk2.port_mg |=
1625 ((qid >> 4) & 0x3);
developerfd40db22021-04-29 10:08:25 +08001626
developerd35bbcc2022-09-28 22:46:01 +08001627 if (((IS_EXT(dev) && (FROM_GE_LAN_GRP(skb) ||
developeraf07fad2021-11-19 17:53:42 +08001628 FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb))) ||
1629 ((mape_toggle && mape == 1) && !FROM_EXT(skb))) &&
1630 (!whnat)) {
1631 entry.ipv4_hnapt.etype = htons(HQOS_MAGIC_TAG);
1632 entry.ipv4_hnapt.vlan1 = skb_hnat_entry(skb);
1633 entry.bfib1.vlan_layer = 1;
1634 }
developerfd40db22021-04-29 10:08:25 +08001635 }
developerfd40db22021-04-29 10:08:25 +08001636
developer34028fb2022-01-11 13:51:29 +08001637 if (FROM_EXT(skb) || skb_hnat_sport(skb) == NR_QDMA_PORT ||
1638 (IS_PPPQ_MODE && !IS_DSA_LAN(dev) && !IS_DSA_WAN(dev)))
developeraf07fad2021-11-19 17:53:42 +08001639 entry.ipv4_hnapt.iblk2.fqos = 0;
1640 else
developerd35bbcc2022-09-28 22:46:01 +08001641#if defined(CONFIG_MEDIATEK_NETSYS_V3)
developer934756a2022-11-18 14:51:34 +08001642 if ((IS_HQOS_UL_MODE && IS_WAN(dev)) ||
developer493adc32022-11-29 22:34:18 +08001643 (IS_HQOS_DL_MODE && IS_LAN_GRP(dev)) ||
developer934756a2022-11-18 14:51:34 +08001644 (IS_PPPQ_MODE &&
1645 IS_PPPQ_PATH(dev, skb)))
developer47545a32022-11-15 16:06:58 +08001646 entry.ipv4_hnapt.tport_id = 1;
1647 else
1648 entry.ipv4_hnapt.tport_id = 0;
developerd35bbcc2022-09-28 22:46:01 +08001649#else
developer399ec072022-06-24 16:07:41 +08001650 entry.ipv4_hnapt.iblk2.fqos =
developer934756a2022-11-18 14:51:34 +08001651 (!IS_PPPQ_MODE ||
1652 (IS_PPPQ_MODE &&
1653 IS_PPPQ_PATH(dev, skb)));
developerd35bbcc2022-09-28 22:46:01 +08001654#endif
developeraf07fad2021-11-19 17:53:42 +08001655 } else {
developerfd40db22021-04-29 10:08:25 +08001656 entry.ipv4_hnapt.iblk2.fqos = 0;
developeraf07fad2021-11-19 17:53:42 +08001657 }
developerfd40db22021-04-29 10:08:25 +08001658 } else {
1659 entry.ipv6_5t_route.iblk2.dp = gmac;
1660 entry.ipv6_5t_route.iblk2.port_mg =
developer4164cfe2022-12-01 11:27:41 +08001661 (hnat_priv->data->version == MTK_HNAT_V1_1) ? 0x3f : 0;
developer24948202021-11-24 17:38:27 +08001662
developeraf07fad2021-11-19 17:53:42 +08001663 if (qos_toggle) {
developer4164cfe2022-12-01 11:27:41 +08001664 if (hnat_priv->data->version == MTK_HNAT_V2 ||
1665 hnat_priv->data->version == MTK_HNAT_V3) {
developeraf07fad2021-11-19 17:53:42 +08001666 entry.ipv6_5t_route.iblk2.qid = qid & 0x7f;
1667 } else {
1668 /* qid[5:0]= port_mg[1:0]+ qid[3:0] */
1669 entry.ipv6_5t_route.iblk2.qid = qid & 0xf;
developer4164cfe2022-12-01 11:27:41 +08001670 if (hnat_priv->data->version != MTK_HNAT_V1_1)
developeraf07fad2021-11-19 17:53:42 +08001671 entry.ipv6_5t_route.iblk2.port_mg |=
1672 ((qid >> 4) & 0x3);
developerfd40db22021-04-29 10:08:25 +08001673
developerd35bbcc2022-09-28 22:46:01 +08001674 if (IS_EXT(dev) && (FROM_GE_LAN_GRP(skb) ||
developeraf07fad2021-11-19 17:53:42 +08001675 FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb)) &&
1676 (!whnat)) {
1677 entry.ipv6_5t_route.etype = htons(HQOS_MAGIC_TAG);
1678 entry.ipv6_5t_route.vlan1 = skb_hnat_entry(skb);
1679 entry.bfib1.vlan_layer = 1;
1680 }
developerfd40db22021-04-29 10:08:25 +08001681 }
developerfd40db22021-04-29 10:08:25 +08001682
developer34028fb2022-01-11 13:51:29 +08001683 if (FROM_EXT(skb) ||
1684 (IS_PPPQ_MODE && !IS_DSA_LAN(dev) && !IS_DSA_WAN(dev)))
developeraf07fad2021-11-19 17:53:42 +08001685 entry.ipv6_5t_route.iblk2.fqos = 0;
1686 else
developerd35bbcc2022-09-28 22:46:01 +08001687#if defined(CONFIG_MEDIATEK_NETSYS_V3)
developer934756a2022-11-18 14:51:34 +08001688 if ((IS_HQOS_UL_MODE && IS_WAN(dev)) ||
developer493adc32022-11-29 22:34:18 +08001689 (IS_HQOS_DL_MODE && IS_LAN_GRP(dev)) ||
developer934756a2022-11-18 14:51:34 +08001690 (IS_PPPQ_MODE &&
1691 IS_PPPQ_PATH(dev, skb)))
developer47545a32022-11-15 16:06:58 +08001692 entry.ipv6_5t_route.tport_id = 1;
1693 else
1694 entry.ipv6_5t_route.tport_id = 0;
developerd35bbcc2022-09-28 22:46:01 +08001695#else
developer399ec072022-06-24 16:07:41 +08001696 entry.ipv6_5t_route.iblk2.fqos =
developer934756a2022-11-18 14:51:34 +08001697 (!IS_PPPQ_MODE ||
1698 (IS_PPPQ_MODE &&
1699 IS_PPPQ_PATH(dev, skb)));
developerd35bbcc2022-09-28 22:46:01 +08001700#endif
developeraf07fad2021-11-19 17:53:42 +08001701 } else {
developerfd40db22021-04-29 10:08:25 +08001702 entry.ipv6_5t_route.iblk2.fqos = 0;
developeraf07fad2021-11-19 17:53:42 +08001703 }
developerfd40db22021-04-29 10:08:25 +08001704 }
1705
developer60e60962021-06-15 21:05:07 +08001706 /* The INFO2.port_mg and 2nd VLAN ID fields of PPE entry are redefined
1707 * by Wi-Fi whnat engine. These data and INFO2.dp will be updated and
1708 * the entry is set to BIND state in mtk_sw_nat_hook_tx().
1709 */
developer7b36dca2022-05-19 18:29:10 +08001710 if (!whnat) {
1711 entry.bfib1.ttl = 1;
developer60e60962021-06-15 21:05:07 +08001712 entry.bfib1.state = BIND;
developer7b36dca2022-05-19 18:29:10 +08001713 }
developer60e60962021-06-15 21:05:07 +08001714
developerbc552cc2022-03-15 16:19:27 +08001715 wmb();
developerfd40db22021-04-29 10:08:25 +08001716 memcpy(foe, &entry, sizeof(entry));
1717 /*reset statistic for this entry*/
developer577ad2f2022-11-28 10:33:36 +08001718 if (hnat_priv->data->per_flow_accounting &&
1719 skb_hnat_entry(skb) < hnat_priv->foe_etry_num &&
1720 skb_hnat_ppe(skb) < CFG_PPE_NUM)
developer471f6562021-05-10 20:48:34 +08001721 memset(&hnat_priv->acct[skb_hnat_ppe(skb)][skb_hnat_entry(skb)],
1722 0, sizeof(struct mib_entry));
developerfd40db22021-04-29 10:08:25 +08001723
developerfdfe1572021-09-13 16:56:33 +08001724 skb_hnat_filled(skb) = HNAT_INFO_FILLED;
developerfd40db22021-04-29 10:08:25 +08001725
1726 return 0;
1727}
1728
1729int mtk_sw_nat_hook_tx(struct sk_buff *skb, int gmac_no)
1730{
1731 struct foe_entry *entry;
1732 struct ethhdr *eth;
developerbc552cc2022-03-15 16:19:27 +08001733 struct hnat_bind_info_blk bfib1_tx;
developerfd40db22021-04-29 10:08:25 +08001734
developerfdfe1572021-09-13 16:56:33 +08001735 if (skb_hnat_alg(skb) || !is_hnat_info_filled(skb) ||
1736 !is_magic_tag_valid(skb) || !IS_SPACE_AVAILABLE_HEAD(skb))
developerfd40db22021-04-29 10:08:25 +08001737 return NF_ACCEPT;
1738
1739 trace_printk(
1740 "[%s]entry=%x reason=%x gmac_no=%x wdmaid=%x rxid=%x wcid=%x bssid=%x\n",
1741 __func__, skb_hnat_entry(skb), skb_hnat_reason(skb), gmac_no,
1742 skb_hnat_wdma_id(skb), skb_hnat_bss_id(skb),
1743 skb_hnat_wc_id(skb), skb_hnat_rx_id(skb));
1744
developer99506e52021-06-30 22:03:02 +08001745 if ((gmac_no != NR_WDMA0_PORT) && (gmac_no != NR_WDMA1_PORT) &&
1746 (gmac_no != NR_WHNAT_WDMA_PORT))
1747 return NF_ACCEPT;
1748
developerc0419aa2022-12-07 15:56:36 +08001749 if (unlikely(!skb_mac_header_was_set(skb)))
1750 return NF_ACCEPT;
1751
developerfd40db22021-04-29 10:08:25 +08001752 if (!skb_hnat_is_hashed(skb))
1753 return NF_ACCEPT;
1754
developer955a6f62021-07-26 10:54:39 +08001755 if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
1756 skb_hnat_ppe(skb) >= CFG_PPE_NUM)
1757 return NF_ACCEPT;
1758
developer471f6562021-05-10 20:48:34 +08001759 entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
developerfd40db22021-04-29 10:08:25 +08001760 if (entry_hnat_is_bound(entry))
1761 return NF_ACCEPT;
1762
1763 if (skb_hnat_reason(skb) != HIT_UNBIND_RATE_REACH)
1764 return NF_ACCEPT;
1765
1766 eth = eth_hdr(skb);
developerbc552cc2022-03-15 16:19:27 +08001767 memcpy(&bfib1_tx, &entry->bfib1, sizeof(entry->bfib1));
developer8116b0a2021-08-23 18:07:20 +08001768
1769 /*not bind multicast if PPE mcast not enable*/
developerfdfe1572021-09-13 16:56:33 +08001770 if (!hnat_priv->data->mcast) {
1771 if (is_multicast_ether_addr(eth->h_dest))
1772 return NF_ACCEPT;
1773
1774 if (IS_IPV4_GRP(entry))
1775 entry->ipv4_hnapt.iblk2.mcast = 0;
1776 else
1777 entry->ipv6_5t_route.iblk2.mcast = 0;
1778 }
developerfd40db22021-04-29 10:08:25 +08001779
1780 /* Some mt_wifi virtual interfaces, such as apcli,
1781 * will change the smac for specail purpose.
1782 */
developer5ffc5f12022-10-25 18:51:46 +08001783 switch ((int)bfib1_tx.pkt_type) {
developerfd40db22021-04-29 10:08:25 +08001784 case IPV4_HNAPT:
1785 case IPV4_HNAT:
1786 entry->ipv4_hnapt.smac_hi = swab32(*((u32 *)eth->h_source));
1787 entry->ipv4_hnapt.smac_lo = swab16(*((u16 *)&eth->h_source[4]));
1788 break;
1789 case IPV4_DSLITE:
1790 case IPV4_MAP_E:
1791 case IPV6_6RD:
1792 case IPV6_5T_ROUTE:
1793 case IPV6_3T_ROUTE:
developer5ffc5f12022-10-25 18:51:46 +08001794 case IPV6_HNAPT:
1795 case IPV6_HNAT:
developerfd40db22021-04-29 10:08:25 +08001796 entry->ipv6_5t_route.smac_hi = swab32(*((u32 *)eth->h_source));
1797 entry->ipv6_5t_route.smac_lo = swab16(*((u16 *)&eth->h_source[4]));
1798 break;
1799 }
1800
developer0ff76882021-10-26 10:54:13 +08001801 if (skb->vlan_tci) {
developerbc552cc2022-03-15 16:19:27 +08001802 bfib1_tx.vlan_layer = 1;
1803 bfib1_tx.vpm = 1;
developer0ff76882021-10-26 10:54:13 +08001804 if (IS_IPV4_GRP(entry)) {
1805 entry->ipv4_hnapt.etype = htons(ETH_P_8021Q);
developer00a07372022-03-11 16:04:34 +08001806 entry->ipv4_hnapt.vlan1 = skb->vlan_tci;
developer0ff76882021-10-26 10:54:13 +08001807 } else if (IS_IPV6_GRP(entry)) {
1808 entry->ipv6_5t_route.etype = htons(ETH_P_8021Q);
developer00a07372022-03-11 16:04:34 +08001809 entry->ipv6_5t_route.vlan1 = skb->vlan_tci;
developer0ff76882021-10-26 10:54:13 +08001810 }
1811 } else {
developerbc552cc2022-03-15 16:19:27 +08001812 bfib1_tx.vpm = 0;
1813 bfib1_tx.vlan_layer = 0;
developer0ff76882021-10-26 10:54:13 +08001814 }
developer60e60962021-06-15 21:05:07 +08001815
developerfd40db22021-04-29 10:08:25 +08001816 /* MT7622 wifi hw_nat not support QoS */
1817 if (IS_IPV4_GRP(entry)) {
1818 entry->ipv4_hnapt.iblk2.fqos = 0;
developer4164cfe2022-12-01 11:27:41 +08001819 if ((hnat_priv->data->version == MTK_HNAT_V1_2 &&
developere567ad32021-05-25 17:16:17 +08001820 gmac_no == NR_WHNAT_WDMA_PORT) ||
developer4164cfe2022-12-01 11:27:41 +08001821 ((hnat_priv->data->version == MTK_HNAT_V2 ||
1822 hnat_priv->data->version == MTK_HNAT_V3) &&
developere567ad32021-05-25 17:16:17 +08001823 (gmac_no == NR_WDMA0_PORT || gmac_no == NR_WDMA1_PORT))) {
developerfd40db22021-04-29 10:08:25 +08001824 entry->ipv4_hnapt.winfo.bssid = skb_hnat_bss_id(skb);
1825 entry->ipv4_hnapt.winfo.wcid = skb_hnat_wc_id(skb);
developerd35bbcc2022-09-28 22:46:01 +08001826#if defined(CONFIG_MEDIATEK_NETSYS_V3)
developer47545a32022-11-15 16:06:58 +08001827 entry->ipv4_hnapt.tport_id = IS_HQOS_DL_MODE ? 1 : 0;
developerd35bbcc2022-09-28 22:46:01 +08001828 entry->ipv4_hnapt.iblk2.rxid = skb_hnat_rx_id(skb);
1829 entry->ipv4_hnapt.iblk2.winfoi = 1;
1830 entry->ipv4_hnapt.winfo_pao.usr_info =
1831 skb_hnat_usr_info(skb);
1832 entry->ipv4_hnapt.winfo_pao.tid = skb_hnat_tid(skb);
1833 entry->ipv4_hnapt.winfo_pao.is_fixedrate =
1834 skb_hnat_is_fixedrate(skb);
1835 entry->ipv4_hnapt.winfo_pao.is_prior =
1836 skb_hnat_is_prior(skb);
1837 entry->ipv4_hnapt.winfo_pao.is_sp = skb_hnat_is_sp(skb);
1838 entry->ipv4_hnapt.winfo_pao.hf = skb_hnat_hf(skb);
1839 entry->ipv4_hnapt.winfo_pao.amsdu = skb_hnat_amsdu(skb);
1840#elif defined(CONFIG_MEDIATEK_NETSYS_V2)
developerfd40db22021-04-29 10:08:25 +08001841 entry->ipv4_hnapt.iblk2.rxid = skb_hnat_rx_id(skb);
1842 entry->ipv4_hnapt.iblk2.winfoi = 1;
1843#else
1844 entry->ipv4_hnapt.winfo.rxid = skb_hnat_rx_id(skb);
1845 entry->ipv4_hnapt.iblk2w.winfoi = 1;
1846 entry->ipv4_hnapt.iblk2w.wdmaid = skb_hnat_wdma_id(skb);
1847#endif
1848 } else {
1849 if (IS_GMAC1_MODE && !hnat_dsa_is_enable(hnat_priv)) {
developerbc552cc2022-03-15 16:19:27 +08001850 bfib1_tx.vpm = 1;
1851 bfib1_tx.vlan_layer = 1;
developerfd40db22021-04-29 10:08:25 +08001852
developerd35bbcc2022-09-28 22:46:01 +08001853 if (FROM_GE_LAN_GRP(skb))
developerfd40db22021-04-29 10:08:25 +08001854 entry->ipv4_hnapt.vlan1 = 1;
1855 else if (FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb))
1856 entry->ipv4_hnapt.vlan1 = 2;
1857 }
1858
developer34028fb2022-01-11 13:51:29 +08001859 if (IS_HQOS_MODE &&
developerd35bbcc2022-09-28 22:46:01 +08001860 (FROM_GE_LAN_GRP(skb) || FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb))) {
developerbc552cc2022-03-15 16:19:27 +08001861 bfib1_tx.vpm = 0;
1862 bfib1_tx.vlan_layer = 1;
developerfd40db22021-04-29 10:08:25 +08001863 entry->ipv4_hnapt.etype = htons(HQOS_MAGIC_TAG);
1864 entry->ipv4_hnapt.vlan1 = skb_hnat_entry(skb);
1865 entry->ipv4_hnapt.iblk2.fqos = 1;
1866 }
developerfd40db22021-04-29 10:08:25 +08001867 }
1868 entry->ipv4_hnapt.iblk2.dp = gmac_no;
developer5ffc5f12022-10-25 18:51:46 +08001869#if defined(CONFIG_MEDIATEK_NETSYS_V3)
1870 } else if (IS_IPV6_HNAPT(entry) || IS_IPV6_HNAT(entry)) {
1871 entry->ipv6_hnapt.iblk2.dp = gmac_no;
1872 entry->ipv6_hnapt.iblk2.rxid = skb_hnat_rx_id(skb);
1873 entry->ipv6_hnapt.iblk2.winfoi = 1;
1874
1875 entry->ipv6_hnapt.winfo.bssid = skb_hnat_bss_id(skb);
1876 entry->ipv6_hnapt.winfo.wcid = skb_hnat_wc_id(skb);
1877 entry->ipv6_hnapt.winfo_pao.usr_info = skb_hnat_usr_info(skb);
1878 entry->ipv6_hnapt.winfo_pao.tid = skb_hnat_tid(skb);
1879 entry->ipv6_hnapt.winfo_pao.is_fixedrate =
1880 skb_hnat_is_fixedrate(skb);
1881 entry->ipv6_hnapt.winfo_pao.is_prior = skb_hnat_is_prior(skb);
1882 entry->ipv6_hnapt.winfo_pao.is_sp = skb_hnat_is_sp(skb);
1883 entry->ipv6_hnapt.winfo_pao.hf = skb_hnat_hf(skb);
1884 entry->ipv6_hnapt.winfo_pao.amsdu = skb_hnat_amsdu(skb);
developer47545a32022-11-15 16:06:58 +08001885 entry->ipv6_hnapt.tport_id = IS_HQOS_DL_MODE ? 1 : 0;
developer5ffc5f12022-10-25 18:51:46 +08001886#endif
developerfd40db22021-04-29 10:08:25 +08001887 } else {
1888 entry->ipv6_5t_route.iblk2.fqos = 0;
developer4164cfe2022-12-01 11:27:41 +08001889 if ((hnat_priv->data->version == MTK_HNAT_V1_2 &&
developere567ad32021-05-25 17:16:17 +08001890 gmac_no == NR_WHNAT_WDMA_PORT) ||
developer4164cfe2022-12-01 11:27:41 +08001891 ((hnat_priv->data->version == MTK_HNAT_V2 ||
1892 hnat_priv->data->version == MTK_HNAT_V3) &&
developere567ad32021-05-25 17:16:17 +08001893 (gmac_no == NR_WDMA0_PORT || gmac_no == NR_WDMA1_PORT))) {
developerfd40db22021-04-29 10:08:25 +08001894 entry->ipv6_5t_route.winfo.bssid = skb_hnat_bss_id(skb);
1895 entry->ipv6_5t_route.winfo.wcid = skb_hnat_wc_id(skb);
developerd35bbcc2022-09-28 22:46:01 +08001896#if defined(CONFIG_MEDIATEK_NETSYS_V3)
developer47545a32022-11-15 16:06:58 +08001897 entry->ipv6_5t_route.tport_id = IS_HQOS_DL_MODE ? 1 : 0;
developerfd40db22021-04-29 10:08:25 +08001898 entry->ipv6_5t_route.iblk2.rxid = skb_hnat_rx_id(skb);
1899 entry->ipv6_5t_route.iblk2.winfoi = 1;
developerd35bbcc2022-09-28 22:46:01 +08001900 entry->ipv6_5t_route.winfo_pao.usr_info =
1901 skb_hnat_usr_info(skb);
1902 entry->ipv6_5t_route.winfo_pao.tid =
1903 skb_hnat_tid(skb);
1904 entry->ipv6_5t_route.winfo_pao.is_fixedrate =
1905 skb_hnat_is_fixedrate(skb);
1906 entry->ipv6_5t_route.winfo_pao.is_prior =
1907 skb_hnat_is_prior(skb);
1908 entry->ipv6_5t_route.winfo_pao.is_sp =
1909 skb_hnat_is_sp(skb);
1910 entry->ipv6_5t_route.winfo_pao.hf =
1911 skb_hnat_hf(skb);
1912 entry->ipv6_5t_route.winfo_pao.amsdu =
1913 skb_hnat_amsdu(skb);
1914#elif defined(CONFIG_MEDIATEK_NETSYS_V2)
1915 entry->ipv6_5t_route.iblk2.rxid = skb_hnat_rx_id(skb);
1916 entry->ipv6_5t_route.iblk2.winfoi = 1;
developerfd40db22021-04-29 10:08:25 +08001917#else
1918 entry->ipv6_5t_route.winfo.rxid = skb_hnat_rx_id(skb);
1919 entry->ipv6_5t_route.iblk2w.winfoi = 1;
1920 entry->ipv6_5t_route.iblk2w.wdmaid = skb_hnat_wdma_id(skb);
1921#endif
1922 } else {
1923 if (IS_GMAC1_MODE && !hnat_dsa_is_enable(hnat_priv)) {
developerbc552cc2022-03-15 16:19:27 +08001924 bfib1_tx.vpm = 1;
1925 bfib1_tx.vlan_layer = 1;
developerfd40db22021-04-29 10:08:25 +08001926
developerd35bbcc2022-09-28 22:46:01 +08001927 if (FROM_GE_LAN_GRP(skb))
developerfd40db22021-04-29 10:08:25 +08001928 entry->ipv6_5t_route.vlan1 = 1;
1929 else if (FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb))
1930 entry->ipv6_5t_route.vlan1 = 2;
1931 }
1932
developer34028fb2022-01-11 13:51:29 +08001933 if (IS_HQOS_MODE &&
developerd35bbcc2022-09-28 22:46:01 +08001934 (FROM_GE_LAN_GRP(skb) || FROM_GE_WAN(skb) || FROM_GE_VIRTUAL(skb))) {
developerbc552cc2022-03-15 16:19:27 +08001935 bfib1_tx.vpm = 0;
1936 bfib1_tx.vlan_layer = 1;
developerfd40db22021-04-29 10:08:25 +08001937 entry->ipv6_5t_route.etype = htons(HQOS_MAGIC_TAG);
1938 entry->ipv6_5t_route.vlan1 = skb_hnat_entry(skb);
1939 entry->ipv6_5t_route.iblk2.fqos = 1;
1940 }
developerfd40db22021-04-29 10:08:25 +08001941 }
1942 entry->ipv6_5t_route.iblk2.dp = gmac_no;
1943 }
1944
developer7b36dca2022-05-19 18:29:10 +08001945 bfib1_tx.ttl = 1;
developerbc552cc2022-03-15 16:19:27 +08001946 bfib1_tx.state = BIND;
1947 wmb();
1948 memcpy(&entry->bfib1, &bfib1_tx, sizeof(bfib1_tx));
developerfd40db22021-04-29 10:08:25 +08001949
1950 return NF_ACCEPT;
1951}
1952
1953int mtk_sw_nat_hook_rx(struct sk_buff *skb)
1954{
developer99506e52021-06-30 22:03:02 +08001955 if (!IS_SPACE_AVAILABLE_HEAD(skb) || !FROM_WED(skb)) {
1956 skb_hnat_magic_tag(skb) = 0;
developerfd40db22021-04-29 10:08:25 +08001957 return NF_ACCEPT;
developer99506e52021-06-30 22:03:02 +08001958 }
developerfd40db22021-04-29 10:08:25 +08001959
1960 skb_hnat_alg(skb) = 0;
developerfdfe1572021-09-13 16:56:33 +08001961 skb_hnat_filled(skb) = 0;
developerfd40db22021-04-29 10:08:25 +08001962 skb_hnat_magic_tag(skb) = HNAT_MAGIC_TAG;
1963
1964 if (skb_hnat_iface(skb) == FOE_MAGIC_WED0)
1965 skb_hnat_sport(skb) = NR_WDMA0_PORT;
1966 else if (skb_hnat_iface(skb) == FOE_MAGIC_WED1)
1967 skb_hnat_sport(skb) = NR_WDMA1_PORT;
1968
1969 return NF_ACCEPT;
1970}
1971
1972void mtk_ppe_dev_register_hook(struct net_device *dev)
1973{
1974 int i, number = 0;
1975 struct extdev_entry *ext_entry;
1976
developerfd40db22021-04-29 10:08:25 +08001977 for (i = 1; i < MAX_IF_NUM; i++) {
1978 if (hnat_priv->wifi_hook_if[i] == dev) {
1979 pr_info("%s : %s has been registered in wifi_hook_if table[%d]\n",
1980 __func__, dev->name, i);
1981 return;
1982 }
developera7e6c242022-12-05 13:52:40 +08001983 }
1984
1985 for (i = 1; i < MAX_IF_NUM; i++) {
developerfd40db22021-04-29 10:08:25 +08001986 if (!hnat_priv->wifi_hook_if[i]) {
1987 if (find_extif_from_devname(dev->name)) {
1988 extif_set_dev(dev);
1989 goto add_wifi_hook_if;
1990 }
1991
1992 number = get_ext_device_number();
1993 if (number >= MAX_EXT_DEVS) {
1994 pr_info("%s : extdev array is full. %s is not registered\n",
1995 __func__, dev->name);
1996 return;
1997 }
1998
1999 ext_entry = kzalloc(sizeof(*ext_entry), GFP_KERNEL);
2000 if (!ext_entry)
2001 return;
2002
developer4c32b7a2021-11-13 16:46:43 +08002003 strncpy(ext_entry->name, dev->name, IFNAMSIZ - 1);
developerfd40db22021-04-29 10:08:25 +08002004 dev_hold(dev);
2005 ext_entry->dev = dev;
2006 ext_if_add(ext_entry);
2007
2008add_wifi_hook_if:
2009 dev_hold(dev);
2010 hnat_priv->wifi_hook_if[i] = dev;
2011
2012 break;
2013 }
2014 }
2015 pr_info("%s : ineterface %s register (%d)\n", __func__, dev->name, i);
2016}
2017
2018void mtk_ppe_dev_unregister_hook(struct net_device *dev)
2019{
2020 int i;
2021
2022 for (i = 1; i < MAX_IF_NUM; i++) {
2023 if (hnat_priv->wifi_hook_if[i] == dev) {
2024 hnat_priv->wifi_hook_if[i] = NULL;
2025 dev_put(dev);
2026
2027 break;
2028 }
2029 }
2030
2031 extif_put_dev(dev);
2032 pr_info("%s : ineterface %s set null (%d)\n", __func__, dev->name, i);
2033}
2034
2035static unsigned int mtk_hnat_accel_type(struct sk_buff *skb)
2036{
2037 struct dst_entry *dst;
2038 struct nf_conn *ct;
2039 enum ip_conntrack_info ctinfo;
2040 const struct nf_conn_help *help;
2041
2042 /* Do not accelerate 1st round of xfrm flow, and 2nd round of xfrm flow
2043 * is from local_out which is also filtered in sanity check.
2044 */
2045 dst = skb_dst(skb);
2046 if (dst && dst_xfrm(dst))
2047 return 0;
2048
2049 ct = nf_ct_get(skb, &ctinfo);
2050 if (!ct)
2051 return 1;
2052
2053 /* rcu_read_lock()ed by nf_hook_slow */
2054 help = nfct_help(ct);
2055 if (help && rcu_dereference(help->helper))
2056 return 0;
2057
2058 return 1;
2059}
2060
developer6f4a0c72021-10-19 10:04:22 +08002061static void mtk_hnat_dscp_update(struct sk_buff *skb, struct foe_entry *entry)
2062{
2063 struct iphdr *iph;
2064 struct ethhdr *eth;
2065 struct ipv6hdr *ip6h;
2066 bool flag = false;
2067
2068 eth = eth_hdr(skb);
2069 switch (ntohs(eth->h_proto)) {
2070 case ETH_P_IP:
2071 iph = ip_hdr(skb);
developer001e7be2021-12-09 15:00:27 +08002072 if (IS_IPV4_GRP(entry) && entry->ipv4_hnapt.iblk2.dscp != iph->tos)
developer6f4a0c72021-10-19 10:04:22 +08002073 flag = true;
2074 break;
2075 case ETH_P_IPV6:
2076 ip6h = ipv6_hdr(skb);
developer001e7be2021-12-09 15:00:27 +08002077 if ((IS_IPV6_3T_ROUTE(entry) || IS_IPV6_5T_ROUTE(entry)) &&
2078 (entry->ipv6_5t_route.iblk2.dscp !=
2079 (ip6h->priority << 4 | (ip6h->flow_lbl[0] >> 4))))
developer6f4a0c72021-10-19 10:04:22 +08002080 flag = true;
2081 break;
2082 default:
2083 return;
2084 }
2085
2086 if (flag) {
developer1080dd82022-03-07 19:31:04 +08002087 if (debug_level >= 2)
2088 pr_info("Delete entry idx=%d.\n", skb_hnat_entry(skb));
developer6f4a0c72021-10-19 10:04:22 +08002089 memset(entry, 0, sizeof(struct foe_entry));
2090 hnat_cache_ebl(1);
2091 }
2092}
2093
developer30a47682021-11-02 17:06:14 +08002094static void mtk_hnat_nf_update(struct sk_buff *skb)
2095{
2096 struct nf_conn *ct;
2097 struct nf_conn_acct *acct;
2098 struct nf_conn_counter *counter;
2099 enum ip_conntrack_info ctinfo;
2100 struct hnat_accounting diff;
2101
2102 ct = nf_ct_get(skb, &ctinfo);
2103 if (ct) {
2104 if (!hnat_get_count(hnat_priv, skb_hnat_ppe(skb), skb_hnat_entry(skb), &diff))
2105 return;
2106
2107 acct = nf_conn_acct_find(ct);
2108 if (acct) {
2109 counter = acct->counter;
2110 atomic64_add(diff.packets, &counter[CTINFO2DIR(ctinfo)].packets);
2111 atomic64_add(diff.bytes, &counter[CTINFO2DIR(ctinfo)].bytes);
2112 }
2113 }
2114}
2115
developerfd40db22021-04-29 10:08:25 +08002116static unsigned int mtk_hnat_nf_post_routing(
2117 struct sk_buff *skb, const struct net_device *out,
2118 unsigned int (*fn)(struct sk_buff *, const struct net_device *,
2119 struct flow_offload_hw_path *),
2120 const char *func)
2121{
2122 struct foe_entry *entry;
2123 struct flow_offload_hw_path hw_path = { .dev = (struct net_device*)out,
developere5763512021-05-21 01:04:58 +08002124 .virt_dev = (struct net_device*)out };
developerfd40db22021-04-29 10:08:25 +08002125 const struct net_device *arp_dev = out;
2126
2127 if (skb_hnat_alg(skb) || unlikely(!is_magic_tag_valid(skb) ||
2128 !IS_SPACE_AVAILABLE_HEAD(skb)))
2129 return 0;
2130
developerc0419aa2022-12-07 15:56:36 +08002131 if (unlikely(!skb_mac_header_was_set(skb)))
2132 return 0;
2133
developerfd40db22021-04-29 10:08:25 +08002134 if (unlikely(!skb_hnat_is_hashed(skb)))
2135 return 0;
2136
2137 if (out->netdev_ops->ndo_flow_offload_check) {
developere5763512021-05-21 01:04:58 +08002138 out->netdev_ops->ndo_flow_offload_check(&hw_path);
developerfd40db22021-04-29 10:08:25 +08002139 out = (IS_GMAC1_MODE) ? hw_path.virt_dev : hw_path.dev;
2140 }
2141
developerd35bbcc2022-09-28 22:46:01 +08002142 if (!IS_LAN_GRP(out) && !IS_WAN(out) && !IS_EXT(out))
developerfd40db22021-04-29 10:08:25 +08002143 return 0;
2144
2145 trace_printk("[%s] case hit, %x-->%s, reason=%x\n", __func__,
2146 skb_hnat_iface(skb), out->name, skb_hnat_reason(skb));
2147
developer577ad2f2022-11-28 10:33:36 +08002148 if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
2149 skb_hnat_ppe(skb) >= CFG_PPE_NUM)
2150 return -1;
2151
developer471f6562021-05-10 20:48:34 +08002152 entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
developerfd40db22021-04-29 10:08:25 +08002153
2154 switch (skb_hnat_reason(skb)) {
2155 case HIT_UNBIND_RATE_REACH:
2156 if (entry_hnat_is_bound(entry))
2157 break;
2158
2159 if (fn && !mtk_hnat_accel_type(skb))
2160 break;
2161
2162 if (fn && fn(skb, arp_dev, &hw_path))
2163 break;
2164
2165 skb_to_hnat_info(skb, out, entry, &hw_path);
2166 break;
2167 case HIT_BIND_KEEPALIVE_DUP_OLD_HDR:
developer30a47682021-11-02 17:06:14 +08002168 /* update hnat count to nf_conntrack by keepalive */
2169 if (hnat_priv->data->per_flow_accounting && hnat_priv->nf_stat_en)
2170 mtk_hnat_nf_update(skb);
2171
developerfd40db22021-04-29 10:08:25 +08002172 if (fn && !mtk_hnat_accel_type(skb))
2173 break;
2174
developer6f4a0c72021-10-19 10:04:22 +08002175 /* update dscp for qos */
2176 mtk_hnat_dscp_update(skb, entry);
2177
developerfd40db22021-04-29 10:08:25 +08002178 /* update mcast timestamp*/
developer4164cfe2022-12-01 11:27:41 +08002179 if (hnat_priv->data->version == MTK_HNAT_V1_3 &&
developerfd40db22021-04-29 10:08:25 +08002180 hnat_priv->data->mcast && entry->bfib1.sta == 1)
2181 entry->ipv4_hnapt.m_timestamp = foe_timestamp(hnat_priv);
2182
2183 if (entry_hnat_is_bound(entry)) {
2184 memset(skb_hnat_info(skb), 0, FOE_INFO_LEN);
2185
2186 return -1;
2187 }
2188 break;
2189 case HIT_BIND_MULTICAST_TO_CPU:
2190 case HIT_BIND_MULTICAST_TO_GMAC_CPU:
2191 /*do not forward to gdma again,if ppe already done it*/
developerd35bbcc2022-09-28 22:46:01 +08002192 if (IS_LAN_GRP(out) || IS_WAN(out))
developerfd40db22021-04-29 10:08:25 +08002193 return -1;
2194 break;
2195 }
2196
2197 return 0;
2198}
2199
2200static unsigned int
2201mtk_hnat_ipv6_nf_local_out(void *priv, struct sk_buff *skb,
2202 const struct nf_hook_state *state)
2203{
2204 struct foe_entry *entry;
2205 struct ipv6hdr *ip6h;
2206 struct iphdr _iphdr;
2207 const struct iphdr *iph;
2208 struct tcpudphdr _ports;
2209 const struct tcpudphdr *pptr;
2210 int udp = 0;
2211
2212 if (unlikely(!skb_hnat_is_hashed(skb)))
2213 return NF_ACCEPT;
2214
developer577ad2f2022-11-28 10:33:36 +08002215 if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
2216 skb_hnat_ppe(skb) >= CFG_PPE_NUM)
2217 return NF_ACCEPT;
2218
developer471f6562021-05-10 20:48:34 +08002219 entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
developerfd40db22021-04-29 10:08:25 +08002220 if (skb_hnat_reason(skb) == HIT_UNBIND_RATE_REACH) {
2221 ip6h = ipv6_hdr(skb);
2222 if (ip6h->nexthdr == NEXTHDR_IPIP) {
2223 /* Map-E LAN->WAN: need to record orig info before fn. */
2224 if (mape_toggle) {
2225 iph = skb_header_pointer(skb, IPV6_HDR_LEN,
2226 sizeof(_iphdr), &_iphdr);
developer4c32b7a2021-11-13 16:46:43 +08002227 if (unlikely(!iph))
2228 return NF_ACCEPT;
2229
developerfd40db22021-04-29 10:08:25 +08002230 switch (iph->protocol) {
2231 case IPPROTO_UDP:
2232 udp = 1;
2233 case IPPROTO_TCP:
2234 break;
2235
2236 default:
2237 return NF_ACCEPT;
2238 }
2239
2240 pptr = skb_header_pointer(skb, IPV6_HDR_LEN + iph->ihl * 4,
2241 sizeof(_ports), &_ports);
developer4c32b7a2021-11-13 16:46:43 +08002242 if (unlikely(!pptr))
2243 return NF_ACCEPT;
2244
developerfd40db22021-04-29 10:08:25 +08002245 entry->bfib1.udp = udp;
2246
developer25fc8c02022-05-06 16:24:02 +08002247 /* Map-E LAN->WAN record inner IPv4 header info. */
developerd35bbcc2022-09-28 22:46:01 +08002248#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
developerfd40db22021-04-29 10:08:25 +08002249 entry->bfib1.pkt_type = IPV4_MAP_E;
2250 entry->ipv4_dslite.iblk2.dscp = iph->tos;
developerd35bbcc2022-09-28 22:46:01 +08002251 entry->ipv4_mape.new_sip = ntohl(iph->saddr);
2252 entry->ipv4_mape.new_dip = ntohl(iph->daddr);
2253 entry->ipv4_mape.new_sport = ntohs(pptr->src);
2254 entry->ipv4_mape.new_dport = ntohs(pptr->dst);
developerfd40db22021-04-29 10:08:25 +08002255#else
2256 entry->ipv4_hnapt.iblk2.dscp = iph->tos;
2257 entry->ipv4_hnapt.new_sip = ntohl(iph->saddr);
2258 entry->ipv4_hnapt.new_dip = ntohl(iph->daddr);
2259 entry->ipv4_hnapt.new_sport = ntohs(pptr->src);
2260 entry->ipv4_hnapt.new_dport = ntohs(pptr->dst);
2261#endif
2262 } else {
2263 entry->bfib1.pkt_type = IPV4_DSLITE;
2264 }
2265 }
2266 }
2267 return NF_ACCEPT;
2268}
2269
2270static unsigned int
2271mtk_hnat_ipv6_nf_post_routing(void *priv, struct sk_buff *skb,
2272 const struct nf_hook_state *state)
2273{
developer577ad2f2022-11-28 10:33:36 +08002274 if (!skb)
2275 goto drop;
2276
developerfd40db22021-04-29 10:08:25 +08002277 post_routing_print(skb, state->in, state->out, __func__);
2278
2279 if (!mtk_hnat_nf_post_routing(skb, state->out, hnat_ipv6_get_nexthop,
2280 __func__))
2281 return NF_ACCEPT;
2282
developer577ad2f2022-11-28 10:33:36 +08002283drop:
2284 if (skb)
2285 trace_printk(
2286 "%s:drop (iif=0x%x, out_dev=%s, CB2=0x%x, ppe_hash=0x%x,\n"
2287 "sport=0x%x, reason=0x%x, alg=0x%x)\n",
2288 __func__, skb_hnat_iface(skb), state->out->name,
2289 HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
2290 skb_hnat_sport(skb), skb_hnat_reason(skb),
2291 skb_hnat_alg(skb));
developerfd40db22021-04-29 10:08:25 +08002292
2293 return NF_DROP;
2294}
2295
2296static unsigned int
2297mtk_hnat_ipv4_nf_post_routing(void *priv, struct sk_buff *skb,
2298 const struct nf_hook_state *state)
2299{
developer577ad2f2022-11-28 10:33:36 +08002300 if (!skb)
2301 goto drop;
2302
developerfd40db22021-04-29 10:08:25 +08002303 post_routing_print(skb, state->in, state->out, __func__);
2304
2305 if (!mtk_hnat_nf_post_routing(skb, state->out, hnat_ipv4_get_nexthop,
2306 __func__))
2307 return NF_ACCEPT;
2308
developer577ad2f2022-11-28 10:33:36 +08002309drop:
2310 if (skb)
2311 trace_printk(
2312 "%s:drop (iif=0x%x, out_dev=%s, CB2=0x%x, ppe_hash=0x%x,\n"
2313 "sport=0x%x, reason=0x%x, alg=0x%x)\n",
2314 __func__, skb_hnat_iface(skb), state->out->name,
2315 HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
2316 skb_hnat_sport(skb), skb_hnat_reason(skb),
2317 skb_hnat_alg(skb));
developerfd40db22021-04-29 10:08:25 +08002318
2319 return NF_DROP;
2320}
2321
2322static unsigned int
2323mtk_pong_hqos_handler(void *priv, struct sk_buff *skb,
2324 const struct nf_hook_state *state)
2325{
developer659fdeb2022-12-01 23:03:07 +08002326 struct vlan_ethhdr *veth;
2327
2328 if (!skb)
2329 goto drop;
2330
2331 veth = (struct vlan_ethhdr *)skb_mac_header(skb);
developerfd40db22021-04-29 10:08:25 +08002332
developer34028fb2022-01-11 13:51:29 +08002333 if (IS_HQOS_MODE && eth_hdr(skb)->h_proto == HQOS_MAGIC_TAG) {
developerfd40db22021-04-29 10:08:25 +08002334 skb_hnat_entry(skb) = ntohs(veth->h_vlan_TCI) & 0x3fff;
2335 skb_hnat_reason(skb) = HIT_BIND_FORCE_TO_CPU;
2336 }
developerfd40db22021-04-29 10:08:25 +08002337
2338 if (skb_hnat_iface(skb) == FOE_MAGIC_EXT)
2339 clr_from_extge(skb);
2340
2341 /* packets from external devices -> xxx ,step 2, learning stage */
developeraf07fad2021-11-19 17:53:42 +08002342 if (do_ext2ge_fast_learn(state->in, skb) && (!qos_toggle ||
2343 (qos_toggle && eth_hdr(skb)->h_proto != HQOS_MAGIC_TAG))) {
developerfd40db22021-04-29 10:08:25 +08002344 if (!do_hnat_ext_to_ge2(skb, __func__))
2345 return NF_STOLEN;
2346 goto drop;
2347 }
2348
2349 /* packets form ge -> external device */
2350 if (do_ge2ext_fast(state->in, skb)) {
2351 if (!do_hnat_ge_to_ext(skb, __func__))
2352 return NF_STOLEN;
2353 goto drop;
2354 }
2355
2356 return NF_ACCEPT;
developer577ad2f2022-11-28 10:33:36 +08002357
developerfd40db22021-04-29 10:08:25 +08002358drop:
developer577ad2f2022-11-28 10:33:36 +08002359 if (skb)
2360 printk_ratelimited(KERN_WARNING
2361 "%s:drop (in_dev=%s, iif=0x%x, CB2=0x%x, ppe_hash=0x%x,\n"
2362 "sport=0x%x, reason=0x%x, alg=0x%x)\n",
2363 __func__, state->in->name, skb_hnat_iface(skb),
2364 HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
2365 skb_hnat_sport(skb), skb_hnat_reason(skb),
2366 skb_hnat_alg(skb));
developerfd40db22021-04-29 10:08:25 +08002367
2368 return NF_DROP;
2369}
2370
2371static unsigned int
2372mtk_hnat_br_nf_local_out(void *priv, struct sk_buff *skb,
2373 const struct nf_hook_state *state)
2374{
developer577ad2f2022-11-28 10:33:36 +08002375 if (!skb)
2376 goto drop;
2377
developerfd40db22021-04-29 10:08:25 +08002378 post_routing_print(skb, state->in, state->out, __func__);
2379
2380 if (!mtk_hnat_nf_post_routing(skb, state->out, 0, __func__))
2381 return NF_ACCEPT;
2382
developer577ad2f2022-11-28 10:33:36 +08002383drop:
2384 if (skb)
2385 trace_printk(
2386 "%s:drop (iif=0x%x, out_dev=%s, CB2=0x%x, ppe_hash=0x%x,\n"
2387 "sport=0x%x, reason=0x%x, alg=0x%x)\n",
2388 __func__, skb_hnat_iface(skb), state->out->name,
2389 HNAT_SKB_CB2(skb)->magic, skb_hnat_entry(skb),
2390 skb_hnat_sport(skb), skb_hnat_reason(skb),
2391 skb_hnat_alg(skb));
developerfd40db22021-04-29 10:08:25 +08002392
2393 return NF_DROP;
2394}
2395
2396static unsigned int
2397mtk_hnat_ipv4_nf_local_out(void *priv, struct sk_buff *skb,
2398 const struct nf_hook_state *state)
2399{
2400 struct sk_buff *new_skb;
2401 struct foe_entry *entry;
2402 struct iphdr *iph;
2403
2404 if (!skb_hnat_is_hashed(skb))
2405 return NF_ACCEPT;
2406
developer577ad2f2022-11-28 10:33:36 +08002407 if (skb_hnat_entry(skb) >= hnat_priv->foe_etry_num ||
2408 skb_hnat_ppe(skb) >= CFG_PPE_NUM)
2409 return NF_ACCEPT;
2410
developer471f6562021-05-10 20:48:34 +08002411 entry = &hnat_priv->foe_table_cpu[skb_hnat_ppe(skb)][skb_hnat_entry(skb)];
developerfd40db22021-04-29 10:08:25 +08002412
2413 if (unlikely(skb_headroom(skb) < FOE_INFO_LEN)) {
2414 new_skb = skb_realloc_headroom(skb, FOE_INFO_LEN);
2415 if (!new_skb) {
2416 dev_info(hnat_priv->dev, "%s:drop\n", __func__);
2417 return NF_DROP;
2418 }
2419 dev_kfree_skb(skb);
2420 skb = new_skb;
2421 }
2422
2423 /* Make the flow from local not be bound. */
2424 iph = ip_hdr(skb);
2425 if (iph->protocol == IPPROTO_IPV6) {
2426 entry->udib1.pkt_type = IPV6_6RD;
2427 hnat_set_head_frags(state, skb, 0, hnat_set_alg);
2428 } else {
2429 hnat_set_head_frags(state, skb, 1, hnat_set_alg);
2430 }
2431
2432 return NF_ACCEPT;
2433}
2434
2435static unsigned int mtk_hnat_br_nf_forward(void *priv,
2436 struct sk_buff *skb,
2437 const struct nf_hook_state *state)
2438{
developer4164cfe2022-12-01 11:27:41 +08002439 if ((hnat_priv->data->version == MTK_HNAT_V1_2) &&
developer99506e52021-06-30 22:03:02 +08002440 unlikely(IS_EXT(state->in) && IS_EXT(state->out)))
developerfd40db22021-04-29 10:08:25 +08002441 hnat_set_head_frags(state, skb, 1, hnat_set_alg);
2442
2443 return NF_ACCEPT;
2444}
2445
2446static struct nf_hook_ops mtk_hnat_nf_ops[] __read_mostly = {
2447 {
2448 .hook = mtk_hnat_ipv4_nf_pre_routing,
2449 .pf = NFPROTO_IPV4,
2450 .hooknum = NF_INET_PRE_ROUTING,
2451 .priority = NF_IP_PRI_FIRST + 1,
2452 },
2453 {
2454 .hook = mtk_hnat_ipv6_nf_pre_routing,
2455 .pf = NFPROTO_IPV6,
2456 .hooknum = NF_INET_PRE_ROUTING,
2457 .priority = NF_IP_PRI_FIRST + 1,
2458 },
2459 {
2460 .hook = mtk_hnat_ipv6_nf_post_routing,
2461 .pf = NFPROTO_IPV6,
2462 .hooknum = NF_INET_POST_ROUTING,
2463 .priority = NF_IP_PRI_LAST,
2464 },
2465 {
2466 .hook = mtk_hnat_ipv6_nf_local_out,
2467 .pf = NFPROTO_IPV6,
2468 .hooknum = NF_INET_LOCAL_OUT,
2469 .priority = NF_IP_PRI_LAST,
2470 },
2471 {
2472 .hook = mtk_hnat_ipv4_nf_post_routing,
2473 .pf = NFPROTO_IPV4,
2474 .hooknum = NF_INET_POST_ROUTING,
2475 .priority = NF_IP_PRI_LAST,
2476 },
2477 {
2478 .hook = mtk_hnat_ipv4_nf_local_out,
2479 .pf = NFPROTO_IPV4,
2480 .hooknum = NF_INET_LOCAL_OUT,
2481 .priority = NF_IP_PRI_LAST,
2482 },
2483 {
2484 .hook = mtk_hnat_br_nf_local_in,
2485 .pf = NFPROTO_BRIDGE,
2486 .hooknum = NF_BR_LOCAL_IN,
2487 .priority = NF_BR_PRI_FIRST,
2488 },
2489 {
2490 .hook = mtk_hnat_br_nf_local_out,
2491 .pf = NFPROTO_BRIDGE,
2492 .hooknum = NF_BR_LOCAL_OUT,
2493 .priority = NF_BR_PRI_LAST - 1,
2494 },
2495 {
2496 .hook = mtk_pong_hqos_handler,
2497 .pf = NFPROTO_BRIDGE,
2498 .hooknum = NF_BR_PRE_ROUTING,
developer2b85f652021-08-19 16:09:50 +08002499 .priority = NF_BR_PRI_FIRST + 1,
developerfd40db22021-04-29 10:08:25 +08002500 },
2501};
2502
2503int hnat_register_nf_hooks(void)
2504{
2505 return nf_register_net_hooks(&init_net, mtk_hnat_nf_ops, ARRAY_SIZE(mtk_hnat_nf_ops));
2506}
2507
2508void hnat_unregister_nf_hooks(void)
2509{
2510 nf_unregister_net_hooks(&init_net, mtk_hnat_nf_ops, ARRAY_SIZE(mtk_hnat_nf_ops));
2511}
2512
2513int whnat_adjust_nf_hooks(void)
2514{
2515 struct nf_hook_ops *hook = mtk_hnat_nf_ops;
2516 unsigned int n = ARRAY_SIZE(mtk_hnat_nf_ops);
2517
developerfd40db22021-04-29 10:08:25 +08002518 while (n-- > 0) {
2519 if (hook[n].hook == mtk_hnat_br_nf_local_in) {
2520 hook[n].hooknum = NF_BR_PRE_ROUTING;
developer2b85f652021-08-19 16:09:50 +08002521 hook[n].priority = NF_BR_PRI_FIRST + 1;
developerfd40db22021-04-29 10:08:25 +08002522 } else if (hook[n].hook == mtk_hnat_br_nf_local_out) {
2523 hook[n].hooknum = NF_BR_POST_ROUTING;
2524 } else if (hook[n].hook == mtk_pong_hqos_handler) {
2525 hook[n].hook = mtk_hnat_br_nf_forward;
2526 hook[n].hooknum = NF_BR_FORWARD;
2527 hook[n].priority = NF_BR_PRI_LAST - 1;
2528 }
2529 }
2530
2531 return 0;
2532}
2533
developerfd40db22021-04-29 10:08:25 +08002534int mtk_hqos_ptype_cb(struct sk_buff *skb, struct net_device *dev,
2535 struct packet_type *pt, struct net_device *unused)
2536{
2537 struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb_mac_header(skb);
2538
2539 skb_hnat_entry(skb) = ntohs(veth->h_vlan_TCI) & 0x3fff;
2540 skb_hnat_reason(skb) = HIT_BIND_FORCE_TO_CPU;
2541
developer659fdeb2022-12-01 23:03:07 +08002542 if (do_hnat_ge_to_ext(skb, __func__) == -1)
2543 return 1;
developerfd40db22021-04-29 10:08:25 +08002544
2545 return 0;
2546}
developerfd40db22021-04-29 10:08:25 +08002547