blob: 37d4d5978a2cb002a5ec100188b52fc2123d2ca1 [file] [log] [blame]
developer0fb30d52023-12-04 09:51:36 +08001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2023 MediaTek Inc. All Rights Reserved.
4 *
5 * Author: Ren-Ting Wang <ren-ting.wang@mediatek.com>
6 */
7
8#include "tops/internal.h"
9#include "tops/protocol/mac/eth.h"
10#include "tops/protocol/network/ip.h"
11
12#include <mtk_hnat/nf_hnat_mtk.h>
13
14int
15mtk_tops_eth_encap_param_setup(
16 struct sk_buff *skb,
17 struct tops_params *params,
18 int (*tnl_encap_param_setup)(struct sk_buff *skb,
19 struct tops_params *params))
20{
21 struct ethhdr *eth = eth_hdr(skb);
22
23 params->mac.type = TOPS_MAC_ETH;
24
25 memcpy(&params->mac.eth.h_source, eth->h_source, ETH_ALEN);
26 memcpy(&params->mac.eth.h_dest, eth->h_dest, ETH_ALEN);
27 params->mac.eth.h_proto = htons(ETH_P_IP);
28
29 /*
30 * either has contrusted ethernet header with IP
31 * or the packet is going to do xfrm encryption
32 */
33 if ((ntohs(eth->h_proto) == ETH_P_IP)
34 || (!skb_hnat_cdrt(skb) && skb_dst(skb) && dst_xfrm(skb_dst(skb)))) {
35 return mtk_tops_ip_encap_param_setup(skb,
36 params,
37 tnl_encap_param_setup);
38 }
39
40 TOPS_NOTICE("eth proto not support, proto: 0x%x\n",
41 ntohs(eth->h_proto));
42
43 return -EINVAL;
44}
45
46int mtk_tops_eth_decap_param_setup(struct sk_buff *skb, struct tops_params *params)
47{
48 struct ethhdr *eth;
49 struct ethhdr ethh;
50 int ret = 0;
51
52 skb_push(skb, sizeof(struct ethhdr));
53 eth = skb_header_pointer(skb, 0, sizeof(struct ethhdr), &ethh);
54 if (unlikely(!eth)) {
55 ret = -EINVAL;
56 goto out;
57 }
58
59 if (unlikely(ntohs(eth->h_proto) != ETH_P_IP)) {
60 TOPS_NOTICE("eth proto not support, proto: 0x%x\n",
61 ntohs(eth->h_proto));
62 ret = -EINVAL;
63 goto out;
64 }
65
66 params->mac.type = TOPS_MAC_ETH;
67
68 memcpy(&params->mac.eth.h_source, eth->h_dest, ETH_ALEN);
69 memcpy(&params->mac.eth.h_dest, eth->h_source, ETH_ALEN);
70 params->mac.eth.h_proto = htons(ETH_P_IP);
71
72out:
73 skb_pull(skb, sizeof(struct ethhdr));
74
75 return ret;
76}
77
78static int tops_eth_debug_param_fetch_mac(const char *buf, int *ofs, u8 *mac)
79{
80 int nchar = 0;
81 int ret;
82
83 ret = sscanf(buf + *ofs, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx %n",
84 &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5], &nchar);
85 if (ret != 6)
86 return -EPERM;
87
88 *ofs += nchar;
89
90 return 0;
91}
92
93int mtk_tops_eth_debug_param_setup(const char *buf, int *ofs,
94 struct tops_params *params)
95{
96 char proto[DEBUG_PROTO_LEN] = {0};
97 int ret;
98
99 params->mac.type = TOPS_MAC_ETH;
100
101 ret = tops_eth_debug_param_fetch_mac(buf, ofs, params->mac.eth.h_source);
102 if (ret)
103 return ret;
104
105 ret = tops_eth_debug_param_fetch_mac(buf, ofs, params->mac.eth.h_dest);
106 if (ret)
107 return ret;
108
109 ret = mtk_tops_debug_param_proto_peek(buf, *ofs, proto);
110 if (ret < 0)
111 return ret;
112
113 *ofs += ret;
114
115 if (!strcmp(proto, DEBUG_PROTO_IP)) {
116 params->mac.eth.h_proto = htons(ETH_P_IP);
117 ret = mtk_tops_ip_debug_param_setup(buf, ofs, params);
118 } else {
119 ret = -EINVAL;
120 }
121
122 return ret;
123}
124
125void mtk_tops_eth_param_dump(struct seq_file *s, struct tops_params *params)
126{
127 seq_puts(s, "\tMAC Type: Ethernet ");
128 seq_printf(s, "saddr: %pM daddr: %pM\n",
129 params->mac.eth.h_source, params->mac.eth.h_dest);
130}