12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 233f11d16STom Herbert /* 333f11d16STom Herbert * Copyright (c) 2015 Tom Herbert <tom@herbertland.com> 433f11d16STom Herbert */ 533f11d16STom Herbert 633f11d16STom Herbert #ifndef __ILA_H 733f11d16STom Herbert #define __ILA_H 833f11d16STom Herbert 933f11d16STom Herbert #include <linux/errno.h> 1033f11d16STom Herbert #include <linux/ip.h> 1133f11d16STom Herbert #include <linux/kernel.h> 1233f11d16STom Herbert #include <linux/module.h> 1333f11d16STom Herbert #include <linux/socket.h> 1433f11d16STom Herbert #include <linux/skbuff.h> 1533f11d16STom Herbert #include <linux/types.h> 1633f11d16STom Herbert #include <net/checksum.h> 17ad68147eSTom Herbert #include <net/genetlink.h> 1833f11d16STom Herbert #include <net/ip.h> 1933f11d16STom Herbert #include <net/protocol.h> 2033f11d16STom Herbert #include <uapi/linux/ila.h> 2133f11d16STom Herbert 22351596aaSTom Herbert struct ila_locator { 23351596aaSTom Herbert union { 24351596aaSTom Herbert __u8 v8[8]; 25351596aaSTom Herbert __be16 v16[4]; 26351596aaSTom Herbert __be32 v32[2]; 27351596aaSTom Herbert __be64 v64; 28351596aaSTom Herbert }; 29351596aaSTom Herbert }; 30351596aaSTom Herbert 31351596aaSTom Herbert struct ila_identifier { 32351596aaSTom Herbert union { 33351596aaSTom Herbert struct { 34351596aaSTom Herbert #if defined(__LITTLE_ENDIAN_BITFIELD) 3590bfe662STom Herbert u8 __space:4; 3690bfe662STom Herbert u8 csum_neutral:1; 37351596aaSTom Herbert u8 type:3; 38351596aaSTom Herbert #elif defined(__BIG_ENDIAN_BITFIELD) 39351596aaSTom Herbert u8 type:3; 4090bfe662STom Herbert u8 csum_neutral:1; 4190bfe662STom Herbert u8 __space:4; 42351596aaSTom Herbert #else 43351596aaSTom Herbert #error "Adjust your <asm/byteorder.h> defines" 44351596aaSTom Herbert #endif 45351596aaSTom Herbert u8 __space2[7]; 46351596aaSTom Herbert }; 47351596aaSTom Herbert __u8 v8[8]; 48351596aaSTom Herbert __be16 v16[4]; 49351596aaSTom Herbert __be32 v32[2]; 50351596aaSTom Herbert __be64 v64; 51351596aaSTom Herbert }; 52351596aaSTom Herbert }; 53351596aaSTom Herbert 5490bfe662STom Herbert #define CSUM_NEUTRAL_FLAG htonl(0x10000000) 5590bfe662STom Herbert 56351596aaSTom Herbert struct ila_addr { 57351596aaSTom Herbert union { 58351596aaSTom Herbert struct in6_addr addr; 59351596aaSTom Herbert struct { 60351596aaSTom Herbert struct ila_locator loc; 61351596aaSTom Herbert struct ila_identifier ident; 62351596aaSTom Herbert }; 63351596aaSTom Herbert }; 64351596aaSTom Herbert }; 65351596aaSTom Herbert 66351596aaSTom Herbert static inline struct ila_addr *ila_a2i(struct in6_addr *addr) 67351596aaSTom Herbert { 68351596aaSTom Herbert return (struct ila_addr *)addr; 69351596aaSTom Herbert } 70351596aaSTom Herbert 7133f11d16STom Herbert struct ila_params { 72351596aaSTom Herbert struct ila_locator locator; 73351596aaSTom Herbert struct ila_locator locator_match; 7433f11d16STom Herbert __wsum csum_diff; 7590bfe662STom Herbert u8 csum_mode; 7670d5aef4STom Herbert u8 ident_type; 7733f11d16STom Herbert }; 7833f11d16STom Herbert 7933f11d16STom Herbert static inline __wsum compute_csum_diff8(const __be32 *from, const __be32 *to) 8033f11d16STom Herbert { 8133f11d16STom Herbert __be32 diff[] = { 8233f11d16STom Herbert ~from[0], ~from[1], to[0], to[1], 8333f11d16STom Herbert }; 8433f11d16STom Herbert 8533f11d16STom Herbert return csum_partial(diff, sizeof(diff), 0); 8633f11d16STom Herbert } 8733f11d16STom Herbert 8890bfe662STom Herbert static inline bool ila_csum_neutral_set(struct ila_identifier ident) 8990bfe662STom Herbert { 9090bfe662STom Herbert return !!(ident.csum_neutral); 9190bfe662STom Herbert } 9290bfe662STom Herbert 93707a2ca4STom Herbert void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p, 94707a2ca4STom Herbert bool set_csum_neutral); 9533f11d16STom Herbert 9690bfe662STom Herbert void ila_init_saved_csum(struct ila_params *p); 9790bfe662STom Herbert 98ad68147eSTom Herbert struct ila_net { 99ad68147eSTom Herbert struct { 100ad68147eSTom Herbert struct rhashtable rhash_table; 101ad68147eSTom Herbert spinlock_t *locks; /* Bucket locks for entry manipulation */ 102ad68147eSTom Herbert unsigned int locks_mask; 103ad68147eSTom Herbert bool hooks_registered; 104ad68147eSTom Herbert } xlat; 105ad68147eSTom Herbert }; 106ad68147eSTom Herbert 10733f11d16STom Herbert int ila_lwt_init(void); 10833f11d16STom Herbert void ila_lwt_fini(void); 109ad68147eSTom Herbert 110ad68147eSTom Herbert int ila_xlat_init_net(struct net *net); 111*18a5a169SEric Dumazet void ila_xlat_pre_exit_net(struct net *net); 112ad68147eSTom Herbert void ila_xlat_exit_net(struct net *net); 113ad68147eSTom Herbert 114ad68147eSTom Herbert int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info); 115ad68147eSTom Herbert int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info); 116ad68147eSTom Herbert int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info); 117b6e71bdeSTom Herbert int ila_xlat_nl_cmd_flush(struct sk_buff *skb, struct genl_info *info); 118ad68147eSTom Herbert int ila_xlat_nl_dump_start(struct netlink_callback *cb); 119ad68147eSTom Herbert int ila_xlat_nl_dump_done(struct netlink_callback *cb); 120ad68147eSTom Herbert int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb); 121ad68147eSTom Herbert 122ad68147eSTom Herbert extern unsigned int ila_net_id; 123ad68147eSTom Herbert 124ad68147eSTom Herbert extern struct genl_family ila_nl_family; 12533f11d16STom Herbert 12633f11d16STom Herbert #endif /* __ILA_H */ 127