133181bb8SStanislav Fomichev /* SPDX-License-Identifier: GPL-2.0 */
233181bb8SStanislav Fomichev #ifndef __NETWORK_HELPERS_H
333181bb8SStanislav Fomichev #define __NETWORK_HELPERS_H
433181bb8SStanislav Fomichev #include <sys/socket.h>
533181bb8SStanislav Fomichev #include <sys/types.h>
6488a23b8SStanislav Fomichev #include <linux/types.h>
7488a23b8SStanislav Fomichev typedef __u16 __sum16;
8488a23b8SStanislav Fomichev #include <linux/if_ether.h>
9488a23b8SStanislav Fomichev #include <linux/if_packet.h>
10488a23b8SStanislav Fomichev #include <linux/ip.h>
11488a23b8SStanislav Fomichev #include <linux/ipv6.h>
1290a695c3STushar Vyavahare #include <linux/ethtool.h>
1390a695c3STushar Vyavahare #include <linux/sockios.h>
14e1cdb70dSGeliang Tang #include <linux/err.h>
15488a23b8SStanislav Fomichev #include <netinet/tcp.h>
16488a23b8SStanislav Fomichev #include <bpf/bpf_endian.h>
1790a695c3STushar Vyavahare #include <net/if.h>
18488a23b8SStanislav Fomichev
19488a23b8SStanislav Fomichev #define MAGIC_VAL 0x1234
20488a23b8SStanislav Fomichev #define NUM_ITER 100000
21488a23b8SStanislav Fomichev #define VIP_NUM 5
22488a23b8SStanislav Fomichev #define MAGIC_BYTES 123
23488a23b8SStanislav Fomichev
243d778983SMartin KaFai Lau struct network_helper_opts {
253d778983SMartin KaFai Lau int timeout_ms;
26e15a2209SDaniel Xu int proto;
27a3016a27SGeliang Tang /* +ve: Passed to listen() as-is.
28a3016a27SGeliang Tang * 0: Default when the test does not set
29a3016a27SGeliang Tang * a particular value during the struct init.
30a3016a27SGeliang Tang * It is changed to 1 before passing to listen().
31a3016a27SGeliang Tang * Most tests only have one on-going connection.
32a3016a27SGeliang Tang * -ve: It is changed to 0 before passing to listen().
33a3016a27SGeliang Tang * It is useful to force syncookie without
34a3016a27SGeliang Tang * changing the "tcp_syncookies" sysctl from 1 to 2.
35a3016a27SGeliang Tang */
36a3016a27SGeliang Tang int backlog;
37ed31adf6SGeliang Tang int (*post_socket_cb)(int fd, void *opts);
38e078255aSGeliang Tang void *cb_opts;
393d778983SMartin KaFai Lau };
403d778983SMartin KaFai Lau
41488a23b8SStanislav Fomichev /* ipv4 test vector */
42488a23b8SStanislav Fomichev struct ipv4_packet {
43488a23b8SStanislav Fomichev struct ethhdr eth;
44488a23b8SStanislav Fomichev struct iphdr iph;
45488a23b8SStanislav Fomichev struct tcphdr tcp;
46488a23b8SStanislav Fomichev } __packed;
47488a23b8SStanislav Fomichev extern struct ipv4_packet pkt_v4;
48488a23b8SStanislav Fomichev
49488a23b8SStanislav Fomichev /* ipv6 test vector */
50488a23b8SStanislav Fomichev struct ipv6_packet {
51488a23b8SStanislav Fomichev struct ethhdr eth;
52488a23b8SStanislav Fomichev struct ipv6hdr iph;
53488a23b8SStanislav Fomichev struct tcphdr tcp;
54488a23b8SStanislav Fomichev } __packed;
55488a23b8SStanislav Fomichev extern struct ipv6_packet pkt_v6;
5633181bb8SStanislav Fomichev
57096eccdeSJussi Maki int settimeo(int fd, int timeout_ms);
586f802cb8SGeliang Tang int start_server_str(int family, int type, const char *addr_str, __u16 port,
596f802cb8SGeliang Tang const struct network_helper_opts *opts);
6099126abeSMartin KaFai Lau int start_server(int family, int type, const char *addr, __u16 port,
6199126abeSMartin KaFai Lau int timeout_ms);
62eed92afdSMartin KaFai Lau int *start_reuseport_server(int family, int type, const char *addr_str,
63eed92afdSMartin KaFai Lau __u16 port, int timeout_ms,
64eed92afdSMartin KaFai Lau unsigned int nr_listens);
659c598a83SGeliang Tang int start_server_addr(int type, const struct sockaddr_storage *addr, socklen_t len,
669c598a83SGeliang Tang const struct network_helper_opts *opts);
67eed92afdSMartin KaFai Lau void free_fds(int *fds, unsigned int nr_close_fds);
68bbca57aaSGeliang Tang int client_socket(int family, int type,
69bbca57aaSGeliang Tang const struct network_helper_opts *opts);
70db9994d0SGeliang Tang int connect_to_addr(int type, const struct sockaddr_storage *addr, socklen_t len,
71db9994d0SGeliang Tang const struct network_helper_opts *opts);
72c70b2d90SGeliang Tang int connect_to_addr_str(int family, int type, const char *addr_str, __u16 port,
73c70b2d90SGeliang Tang const struct network_helper_opts *opts);
7499126abeSMartin KaFai Lau int connect_to_fd(int server_fd, int timeout_ms);
75a63507f3SGeliang Tang int connect_to_fd_opts(int server_fd, const struct network_helper_opts *opts);
7699126abeSMartin KaFai Lau int connect_fd_to_fd(int client_fd, int server_fd, int timeout_ms);
778085e1dcSMartin KaFai Lau int fastopen_connect(int server_fd, const char *data, unsigned int data_len,
788085e1dcSMartin KaFai Lau int timeout_ms);
790ab5539fSJakub Sitnicki int make_sockaddr(int family, const char *addr_str, __u16 port,
800ab5539fSJakub Sitnicki struct sockaddr_storage *addr, socklen_t *len);
81372642eaSStanislav Fomichev char *ping_command(int family);
82176ba657SAditi Ghag int get_socket_local_port(int sock_fd);
8390a695c3STushar Vyavahare int get_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param);
84bee3a7b0STushar Vyavahare int set_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param);
8533181bb8SStanislav Fomichev
86a3033884SToke Høiland-Jørgensen struct nstoken;
87a3033884SToke Høiland-Jørgensen /**
88a3033884SToke Høiland-Jørgensen * open_netns() - Switch to specified network namespace by name.
89a3033884SToke Høiland-Jørgensen *
90a3033884SToke Høiland-Jørgensen * Returns token with which to restore the original namespace
91a3033884SToke Høiland-Jørgensen * using close_netns().
92a3033884SToke Høiland-Jørgensen */
93a3033884SToke Høiland-Jørgensen struct nstoken *open_netns(const char *name);
94a3033884SToke Høiland-Jørgensen void close_netns(struct nstoken *token);
95dc34e44eSGeliang Tang int send_recv_data(int lfd, int fd, uint32_t total_bytes);
96*1e115a58SKui-Feng Lee int make_netns(const char *name);
97*1e115a58SKui-Feng Lee int remove_netns(const char *name);
98f6642de0SStanislav Fomichev
csum_fold(__u32 csum)99f6642de0SStanislav Fomichev static __u16 csum_fold(__u32 csum)
100f6642de0SStanislav Fomichev {
101f6642de0SStanislav Fomichev csum = (csum & 0xffff) + (csum >> 16);
102f6642de0SStanislav Fomichev csum = (csum & 0xffff) + (csum >> 16);
103f6642de0SStanislav Fomichev
104f6642de0SStanislav Fomichev return (__u16)~csum;
105f6642de0SStanislav Fomichev }
106f6642de0SStanislav Fomichev
csum_tcpudp_magic(__be32 saddr,__be32 daddr,__u32 len,__u8 proto,__wsum csum)107f6642de0SStanislav Fomichev static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
108f6642de0SStanislav Fomichev __u32 len, __u8 proto,
109f6642de0SStanislav Fomichev __wsum csum)
110f6642de0SStanislav Fomichev {
111f6642de0SStanislav Fomichev __u64 s = csum;
112f6642de0SStanislav Fomichev
113f6642de0SStanislav Fomichev s += (__u32)saddr;
114f6642de0SStanislav Fomichev s += (__u32)daddr;
115f6642de0SStanislav Fomichev s += htons(proto + len);
116f6642de0SStanislav Fomichev s = (s & 0xffffffff) + (s >> 32);
117f6642de0SStanislav Fomichev s = (s & 0xffffffff) + (s >> 32);
118f6642de0SStanislav Fomichev
119f6642de0SStanislav Fomichev return csum_fold((__u32)s);
120f6642de0SStanislav Fomichev }
121f6642de0SStanislav Fomichev
csum_ipv6_magic(const struct in6_addr * saddr,const struct in6_addr * daddr,__u32 len,__u8 proto,__wsum csum)122f6642de0SStanislav Fomichev static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
123f6642de0SStanislav Fomichev const struct in6_addr *daddr,
124f6642de0SStanislav Fomichev __u32 len, __u8 proto,
125f6642de0SStanislav Fomichev __wsum csum)
126f6642de0SStanislav Fomichev {
127f6642de0SStanislav Fomichev __u64 s = csum;
128f6642de0SStanislav Fomichev int i;
129f6642de0SStanislav Fomichev
130f6642de0SStanislav Fomichev for (i = 0; i < 4; i++)
131f6642de0SStanislav Fomichev s += (__u32)saddr->s6_addr32[i];
132f6642de0SStanislav Fomichev for (i = 0; i < 4; i++)
133f6642de0SStanislav Fomichev s += (__u32)daddr->s6_addr32[i];
134f6642de0SStanislav Fomichev s += htons(proto + len);
135f6642de0SStanislav Fomichev s = (s & 0xffffffff) + (s >> 32);
136f6642de0SStanislav Fomichev s = (s & 0xffffffff) + (s >> 32);
137f6642de0SStanislav Fomichev
138f6642de0SStanislav Fomichev return csum_fold((__u32)s);
139f6642de0SStanislav Fomichev }
140f6642de0SStanislav Fomichev
141f52403b6SKui-Feng Lee struct tmonitor_ctx;
142f52403b6SKui-Feng Lee
143f52403b6SKui-Feng Lee #ifdef TRAFFIC_MONITOR
144f52403b6SKui-Feng Lee struct tmonitor_ctx *traffic_monitor_start(const char *netns, const char *test_name,
145f52403b6SKui-Feng Lee const char *subtest_name);
146f52403b6SKui-Feng Lee void traffic_monitor_stop(struct tmonitor_ctx *ctx);
147f52403b6SKui-Feng Lee #else
traffic_monitor_start(const char * netns,const char * test_name,const char * subtest_name)148f52403b6SKui-Feng Lee static inline struct tmonitor_ctx *traffic_monitor_start(const char *netns, const char *test_name,
149f52403b6SKui-Feng Lee const char *subtest_name)
150f52403b6SKui-Feng Lee {
151f52403b6SKui-Feng Lee return NULL;
152f52403b6SKui-Feng Lee }
153f52403b6SKui-Feng Lee
traffic_monitor_stop(struct tmonitor_ctx * ctx)154f52403b6SKui-Feng Lee static inline void traffic_monitor_stop(struct tmonitor_ctx *ctx)
155f52403b6SKui-Feng Lee {
156f52403b6SKui-Feng Lee }
157f52403b6SKui-Feng Lee #endif
158f52403b6SKui-Feng Lee
15933181bb8SStanislav Fomichev #endif
160