blob: ab653e06c2643f79e1dac68b9f10e4e014dec47e [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/protocol/network/ip.h"
9#include "tops/protocol/transport/udp.h"
10
11int mtk_tops_udp_encap_param_setup(
12 struct sk_buff *skb,
13 struct tops_params *params,
14 int (*tnl_encap_param_setup)(struct sk_buff *skb,
15 struct tops_params *params))
16{
17 struct tops_udp_params *udpp = &params->transport.udp;
18 struct udphdr *udp;
19 struct udphdr udph;
20 int ret;
21
22 udp = skb_header_pointer(skb, 0, sizeof(struct udphdr), &udph);
23 if (unlikely(!udp))
24 return -EINVAL;
25
26 params->transport.type = TOPS_TRANSPORT_UDP;
27
28 udpp->sport = udp->source;
29 udpp->dport = udp->dest;
30
31 skb_pull(skb, sizeof(struct udphdr));
32
33 /* udp must be the end of a tunnel */
34 ret = tnl_encap_param_setup(skb, params);
35
36 skb_push(skb, sizeof(struct udphdr));
37
38 return ret;
39}
40
41int mtk_tops_udp_decap_param_setup(struct sk_buff *skb, struct tops_params *params)
42{
43 struct tops_udp_params *udpp = &params->transport.udp;
44 struct udphdr *udp;
45 struct udphdr udph;
46 int ret;
47
48 skb_push(skb, sizeof(struct udphdr));
49 udp = skb_header_pointer(skb, 0, sizeof(struct udphdr), &udph);
50 if (unlikely(!udp)) {
51 ret = -EINVAL;
52 goto out;
53 }
54
55 params->transport.type = TOPS_TRANSPORT_UDP;
56
57 udpp->sport = udp->dest;
58 udpp->dport = udp->source;
59
60 ret = mtk_tops_network_decap_param_setup(skb, params);
61
62out:
63 skb_pull(skb, sizeof(struct udphdr));
64
65 return ret;
66}
67
68static int tops_udp_debug_param_fetch_port(const char *buf, int *ofs, u16 *port)
69{
70 int nchar = 0;
71 int ret;
72 u16 p = 0;
73
74 ret = sscanf(buf + *ofs, "%hu %n", &p, &nchar);
75 if (ret != 1)
76 return -EPERM;
77
78 *port = htons(p);
79
80 *ofs += nchar;
81
82 return 0;
83}
84
85int mtk_tops_udp_debug_param_setup(const char *buf, int *ofs,
86 struct tops_params *params)
87{
88 int ret;
89
90 params->transport.type = TOPS_TRANSPORT_UDP;
91
92 ret = tops_udp_debug_param_fetch_port(buf, ofs, &params->transport.udp.sport);
93 if (ret)
94 return ret;
95
96 ret = tops_udp_debug_param_fetch_port(buf, ofs, &params->transport.udp.dport);
97 if (ret)
98 return ret;
99
100 return ret;
101}
102
103void mtk_tops_udp_param_dump(struct seq_file *s, struct tops_params *params)
104{
105 struct tops_udp_params *udpp = &params->transport.udp;
106
107 seq_puts(s, "\tTransport Type: UDP ");
108 seq_printf(s, "sport: %05u dport: %05u\n",
109 ntohs(udpp->sport), ntohs(udpp->dport));
110}