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; 2643d2b88cSDaniel Borkmann bool must_fail; 27e15a2209SDaniel Xu int proto; 28*a3016a27SGeliang Tang /* +ve: Passed to listen() as-is. 29*a3016a27SGeliang Tang * 0: Default when the test does not set 30*a3016a27SGeliang Tang * a particular value during the struct init. 31*a3016a27SGeliang Tang * It is changed to 1 before passing to listen(). 32*a3016a27SGeliang Tang * Most tests only have one on-going connection. 33*a3016a27SGeliang Tang * -ve: It is changed to 0 before passing to listen(). 34*a3016a27SGeliang Tang * It is useful to force syncookie without 35*a3016a27SGeliang Tang * changing the "tcp_syncookies" sysctl from 1 to 2. 36*a3016a27SGeliang Tang */ 37*a3016a27SGeliang Tang int backlog; 38ed31adf6SGeliang Tang int (*post_socket_cb)(int fd, void *opts); 39e078255aSGeliang Tang void *cb_opts; 403d778983SMartin KaFai Lau }; 413d778983SMartin KaFai Lau 42488a23b8SStanislav Fomichev /* ipv4 test vector */ 43488a23b8SStanislav Fomichev struct ipv4_packet { 44488a23b8SStanislav Fomichev struct ethhdr eth; 45488a23b8SStanislav Fomichev struct iphdr iph; 46488a23b8SStanislav Fomichev struct tcphdr tcp; 47488a23b8SStanislav Fomichev } __packed; 48488a23b8SStanislav Fomichev extern struct ipv4_packet pkt_v4; 49488a23b8SStanislav Fomichev 50488a23b8SStanislav Fomichev /* ipv6 test vector */ 51488a23b8SStanislav Fomichev struct ipv6_packet { 52488a23b8SStanislav Fomichev struct ethhdr eth; 53488a23b8SStanislav Fomichev struct ipv6hdr iph; 54488a23b8SStanislav Fomichev struct tcphdr tcp; 55488a23b8SStanislav Fomichev } __packed; 56488a23b8SStanislav Fomichev extern struct ipv6_packet pkt_v6; 5733181bb8SStanislav Fomichev 58096eccdeSJussi Maki int settimeo(int fd, int timeout_ms); 596f802cb8SGeliang Tang int start_server_str(int family, int type, const char *addr_str, __u16 port, 606f802cb8SGeliang Tang const struct network_helper_opts *opts); 6199126abeSMartin KaFai Lau int start_server(int family, int type, const char *addr, __u16 port, 6299126abeSMartin KaFai Lau int timeout_ms); 63eed92afdSMartin KaFai Lau int *start_reuseport_server(int family, int type, const char *addr_str, 64eed92afdSMartin KaFai Lau __u16 port, int timeout_ms, 65eed92afdSMartin KaFai Lau unsigned int nr_listens); 669c598a83SGeliang Tang int start_server_addr(int type, const struct sockaddr_storage *addr, socklen_t len, 679c598a83SGeliang Tang const struct network_helper_opts *opts); 68eed92afdSMartin KaFai Lau void free_fds(int *fds, unsigned int nr_close_fds); 69bbca57aaSGeliang Tang int client_socket(int family, int type, 70bbca57aaSGeliang Tang const struct network_helper_opts *opts); 71db9994d0SGeliang Tang int connect_to_addr(int type, const struct sockaddr_storage *addr, socklen_t len, 72db9994d0SGeliang Tang const struct network_helper_opts *opts); 7399126abeSMartin KaFai Lau int connect_to_fd(int server_fd, int timeout_ms); 7434ad6ec9SGeliang Tang int connect_to_fd_opts(int server_fd, int type, const struct network_helper_opts *opts); 7599126abeSMartin KaFai Lau int connect_fd_to_fd(int client_fd, int server_fd, int timeout_ms); 768085e1dcSMartin KaFai Lau int fastopen_connect(int server_fd, const char *data, unsigned int data_len, 778085e1dcSMartin KaFai Lau int timeout_ms); 780ab5539fSJakub Sitnicki int make_sockaddr(int family, const char *addr_str, __u16 port, 790ab5539fSJakub Sitnicki struct sockaddr_storage *addr, socklen_t *len); 80372642eaSStanislav Fomichev char *ping_command(int family); 81176ba657SAditi Ghag int get_socket_local_port(int sock_fd); 8290a695c3STushar Vyavahare int get_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param); 83bee3a7b0STushar Vyavahare int set_hw_ring_size(char *ifname, struct ethtool_ringparam *ring_param); 8433181bb8SStanislav Fomichev 85a3033884SToke Høiland-Jørgensen struct nstoken; 86a3033884SToke Høiland-Jørgensen /** 87a3033884SToke Høiland-Jørgensen * open_netns() - Switch to specified network namespace by name. 88a3033884SToke Høiland-Jørgensen * 89a3033884SToke Høiland-Jørgensen * Returns token with which to restore the original namespace 90a3033884SToke Høiland-Jørgensen * using close_netns(). 91a3033884SToke Høiland-Jørgensen */ 92a3033884SToke Høiland-Jørgensen struct nstoken *open_netns(const char *name); 93a3033884SToke Høiland-Jørgensen void close_netns(struct nstoken *token); 94dc34e44eSGeliang Tang int send_recv_data(int lfd, int fd, uint32_t total_bytes); 95f6642de0SStanislav Fomichev 96f6642de0SStanislav Fomichev static __u16 csum_fold(__u32 csum) 97f6642de0SStanislav Fomichev { 98f6642de0SStanislav Fomichev csum = (csum & 0xffff) + (csum >> 16); 99f6642de0SStanislav Fomichev csum = (csum & 0xffff) + (csum >> 16); 100f6642de0SStanislav Fomichev 101f6642de0SStanislav Fomichev return (__u16)~csum; 102f6642de0SStanislav Fomichev } 103f6642de0SStanislav Fomichev 104f6642de0SStanislav Fomichev static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, 105f6642de0SStanislav Fomichev __u32 len, __u8 proto, 106f6642de0SStanislav Fomichev __wsum csum) 107f6642de0SStanislav Fomichev { 108f6642de0SStanislav Fomichev __u64 s = csum; 109f6642de0SStanislav Fomichev 110f6642de0SStanislav Fomichev s += (__u32)saddr; 111f6642de0SStanislav Fomichev s += (__u32)daddr; 112f6642de0SStanislav Fomichev s += htons(proto + len); 113f6642de0SStanislav Fomichev s = (s & 0xffffffff) + (s >> 32); 114f6642de0SStanislav Fomichev s = (s & 0xffffffff) + (s >> 32); 115f6642de0SStanislav Fomichev 116f6642de0SStanislav Fomichev return csum_fold((__u32)s); 117f6642de0SStanislav Fomichev } 118f6642de0SStanislav Fomichev 119f6642de0SStanislav Fomichev static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, 120f6642de0SStanislav Fomichev const struct in6_addr *daddr, 121f6642de0SStanislav Fomichev __u32 len, __u8 proto, 122f6642de0SStanislav Fomichev __wsum csum) 123f6642de0SStanislav Fomichev { 124f6642de0SStanislav Fomichev __u64 s = csum; 125f6642de0SStanislav Fomichev int i; 126f6642de0SStanislav Fomichev 127f6642de0SStanislav Fomichev for (i = 0; i < 4; i++) 128f6642de0SStanislav Fomichev s += (__u32)saddr->s6_addr32[i]; 129f6642de0SStanislav Fomichev for (i = 0; i < 4; i++) 130f6642de0SStanislav Fomichev s += (__u32)daddr->s6_addr32[i]; 131f6642de0SStanislav Fomichev s += htons(proto + len); 132f6642de0SStanislav Fomichev s = (s & 0xffffffff) + (s >> 32); 133f6642de0SStanislav Fomichev s = (s & 0xffffffff) + (s >> 32); 134f6642de0SStanislav Fomichev 135f6642de0SStanislav Fomichev return csum_fold((__u32)s); 136f6642de0SStanislav Fomichev } 137f6642de0SStanislav Fomichev 13833181bb8SStanislav Fomichev #endif 139