xref: /OK3568_Linux_fs/kernel/net/ipv6/ila/ila.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2015 Tom Herbert <tom@herbertland.com>
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #ifndef __ILA_H
7*4882a593Smuzhiyun #define __ILA_H
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/errno.h>
10*4882a593Smuzhiyun #include <linux/ip.h>
11*4882a593Smuzhiyun #include <linux/kernel.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/socket.h>
14*4882a593Smuzhiyun #include <linux/skbuff.h>
15*4882a593Smuzhiyun #include <linux/types.h>
16*4882a593Smuzhiyun #include <net/checksum.h>
17*4882a593Smuzhiyun #include <net/genetlink.h>
18*4882a593Smuzhiyun #include <net/ip.h>
19*4882a593Smuzhiyun #include <net/protocol.h>
20*4882a593Smuzhiyun #include <uapi/linux/ila.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun struct ila_locator {
23*4882a593Smuzhiyun 	union {
24*4882a593Smuzhiyun 		__u8            v8[8];
25*4882a593Smuzhiyun 		__be16          v16[4];
26*4882a593Smuzhiyun 		__be32          v32[2];
27*4882a593Smuzhiyun 		__be64		v64;
28*4882a593Smuzhiyun 	};
29*4882a593Smuzhiyun };
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun struct ila_identifier {
32*4882a593Smuzhiyun 	union {
33*4882a593Smuzhiyun 		struct {
34*4882a593Smuzhiyun #if defined(__LITTLE_ENDIAN_BITFIELD)
35*4882a593Smuzhiyun 			u8 __space:4;
36*4882a593Smuzhiyun 			u8 csum_neutral:1;
37*4882a593Smuzhiyun 			u8 type:3;
38*4882a593Smuzhiyun #elif defined(__BIG_ENDIAN_BITFIELD)
39*4882a593Smuzhiyun 			u8 type:3;
40*4882a593Smuzhiyun 			u8 csum_neutral:1;
41*4882a593Smuzhiyun 			u8 __space:4;
42*4882a593Smuzhiyun #else
43*4882a593Smuzhiyun #error  "Adjust your <asm/byteorder.h> defines"
44*4882a593Smuzhiyun #endif
45*4882a593Smuzhiyun 			u8 __space2[7];
46*4882a593Smuzhiyun 		};
47*4882a593Smuzhiyun 		__u8            v8[8];
48*4882a593Smuzhiyun 		__be16          v16[4];
49*4882a593Smuzhiyun 		__be32          v32[2];
50*4882a593Smuzhiyun 		__be64		v64;
51*4882a593Smuzhiyun 	};
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define CSUM_NEUTRAL_FLAG	htonl(0x10000000)
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun struct ila_addr {
57*4882a593Smuzhiyun 	union {
58*4882a593Smuzhiyun 		struct in6_addr addr;
59*4882a593Smuzhiyun 		struct {
60*4882a593Smuzhiyun 			struct ila_locator loc;
61*4882a593Smuzhiyun 			struct ila_identifier ident;
62*4882a593Smuzhiyun 		};
63*4882a593Smuzhiyun 	};
64*4882a593Smuzhiyun };
65*4882a593Smuzhiyun 
ila_a2i(struct in6_addr * addr)66*4882a593Smuzhiyun static inline struct ila_addr *ila_a2i(struct in6_addr *addr)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	return (struct ila_addr *)addr;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun struct ila_params {
72*4882a593Smuzhiyun 	struct ila_locator locator;
73*4882a593Smuzhiyun 	struct ila_locator locator_match;
74*4882a593Smuzhiyun 	__wsum csum_diff;
75*4882a593Smuzhiyun 	u8 csum_mode;
76*4882a593Smuzhiyun 	u8 ident_type;
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun 
compute_csum_diff8(const __be32 * from,const __be32 * to)79*4882a593Smuzhiyun static inline __wsum compute_csum_diff8(const __be32 *from, const __be32 *to)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	__be32 diff[] = {
82*4882a593Smuzhiyun 		~from[0], ~from[1], to[0], to[1],
83*4882a593Smuzhiyun 	};
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	return csum_partial(diff, sizeof(diff), 0);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun 
ila_csum_neutral_set(struct ila_identifier ident)88*4882a593Smuzhiyun static inline bool ila_csum_neutral_set(struct ila_identifier ident)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	return !!(ident.csum_neutral);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p,
94*4882a593Smuzhiyun 			     bool set_csum_neutral);
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun void ila_init_saved_csum(struct ila_params *p);
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun struct ila_net {
99*4882a593Smuzhiyun 	struct {
100*4882a593Smuzhiyun 		struct rhashtable rhash_table;
101*4882a593Smuzhiyun 		spinlock_t *locks; /* Bucket locks for entry manipulation */
102*4882a593Smuzhiyun 		unsigned int locks_mask;
103*4882a593Smuzhiyun 		bool hooks_registered;
104*4882a593Smuzhiyun 	} xlat;
105*4882a593Smuzhiyun };
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun int ila_lwt_init(void);
108*4882a593Smuzhiyun void ila_lwt_fini(void);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun int ila_xlat_init_net(struct net *net);
111*4882a593Smuzhiyun void ila_xlat_exit_net(struct net *net);
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info);
114*4882a593Smuzhiyun int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info);
115*4882a593Smuzhiyun int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info);
116*4882a593Smuzhiyun int ila_xlat_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info);
117*4882a593Smuzhiyun int ila_xlat_nl_dump_start(struct netlink_callback *cb);
118*4882a593Smuzhiyun int ila_xlat_nl_dump_done(struct netlink_callback *cb);
119*4882a593Smuzhiyun int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb);
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun extern unsigned int ila_net_id;
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun extern struct genl_family ila_nl_family;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun #endif /* __ILA_H */
126