133f11d16STom Herbert /* 233f11d16STom Herbert * Copyright (c) 2015 Tom Herbert <tom@herbertland.com> 333f11d16STom Herbert * 433f11d16STom Herbert * This program is free software; you can redistribute it and/or 533f11d16STom Herbert * modify it under the terms of the GNU General Public License as 633f11d16STom Herbert * published by the Free Software Foundation; either version 2 of 733f11d16STom Herbert * the License, or (at your option) any later version. 833f11d16STom Herbert * 933f11d16STom Herbert */ 1033f11d16STom Herbert 1133f11d16STom Herbert #ifndef __ILA_H 1233f11d16STom Herbert #define __ILA_H 1333f11d16STom Herbert 1433f11d16STom Herbert #include <linux/errno.h> 1533f11d16STom Herbert #include <linux/ip.h> 1633f11d16STom Herbert #include <linux/kernel.h> 1733f11d16STom Herbert #include <linux/module.h> 1833f11d16STom Herbert #include <linux/socket.h> 1933f11d16STom Herbert #include <linux/skbuff.h> 2033f11d16STom Herbert #include <linux/types.h> 2133f11d16STom Herbert #include <net/checksum.h> 22*ad68147eSTom Herbert #include <net/genetlink.h> 2333f11d16STom Herbert #include <net/ip.h> 2433f11d16STom Herbert #include <net/protocol.h> 2533f11d16STom Herbert #include <uapi/linux/ila.h> 2633f11d16STom Herbert 27351596aaSTom Herbert struct ila_locator { 28351596aaSTom Herbert union { 29351596aaSTom Herbert __u8 v8[8]; 30351596aaSTom Herbert __be16 v16[4]; 31351596aaSTom Herbert __be32 v32[2]; 32351596aaSTom Herbert __be64 v64; 33351596aaSTom Herbert }; 34351596aaSTom Herbert }; 35351596aaSTom Herbert 36351596aaSTom Herbert struct ila_identifier { 37351596aaSTom Herbert union { 38351596aaSTom Herbert struct { 39351596aaSTom Herbert #if defined(__LITTLE_ENDIAN_BITFIELD) 4090bfe662STom Herbert u8 __space:4; 4190bfe662STom Herbert u8 csum_neutral:1; 42351596aaSTom Herbert u8 type:3; 43351596aaSTom Herbert #elif defined(__BIG_ENDIAN_BITFIELD) 44351596aaSTom Herbert u8 type:3; 4590bfe662STom Herbert u8 csum_neutral:1; 4690bfe662STom Herbert u8 __space:4; 47351596aaSTom Herbert #else 48351596aaSTom Herbert #error "Adjust your <asm/byteorder.h> defines" 49351596aaSTom Herbert #endif 50351596aaSTom Herbert u8 __space2[7]; 51351596aaSTom Herbert }; 52351596aaSTom Herbert __u8 v8[8]; 53351596aaSTom Herbert __be16 v16[4]; 54351596aaSTom Herbert __be32 v32[2]; 55351596aaSTom Herbert __be64 v64; 56351596aaSTom Herbert }; 57351596aaSTom Herbert }; 58351596aaSTom Herbert 5990bfe662STom Herbert #define CSUM_NEUTRAL_FLAG htonl(0x10000000) 6090bfe662STom Herbert 61351596aaSTom Herbert struct ila_addr { 62351596aaSTom Herbert union { 63351596aaSTom Herbert struct in6_addr addr; 64351596aaSTom Herbert struct { 65351596aaSTom Herbert struct ila_locator loc; 66351596aaSTom Herbert struct ila_identifier ident; 67351596aaSTom Herbert }; 68351596aaSTom Herbert }; 69351596aaSTom Herbert }; 70351596aaSTom Herbert 71351596aaSTom Herbert static inline struct ila_addr *ila_a2i(struct in6_addr *addr) 72351596aaSTom Herbert { 73351596aaSTom Herbert return (struct ila_addr *)addr; 74351596aaSTom Herbert } 75351596aaSTom Herbert 76351596aaSTom Herbert static inline bool ila_addr_is_ila(struct ila_addr *iaddr) 77351596aaSTom Herbert { 78351596aaSTom Herbert return (iaddr->ident.type != ILA_ATYPE_IID); 79351596aaSTom Herbert } 80351596aaSTom Herbert 8133f11d16STom Herbert struct ila_params { 82351596aaSTom Herbert struct ila_locator locator; 83351596aaSTom Herbert struct ila_locator locator_match; 8433f11d16STom Herbert __wsum csum_diff; 8590bfe662STom Herbert u8 csum_mode; 8670d5aef4STom Herbert u8 ident_type; 8733f11d16STom Herbert }; 8833f11d16STom Herbert 8933f11d16STom Herbert static inline __wsum compute_csum_diff8(const __be32 *from, const __be32 *to) 9033f11d16STom Herbert { 9133f11d16STom Herbert __be32 diff[] = { 9233f11d16STom Herbert ~from[0], ~from[1], to[0], to[1], 9333f11d16STom Herbert }; 9433f11d16STom Herbert 9533f11d16STom Herbert return csum_partial(diff, sizeof(diff), 0); 9633f11d16STom Herbert } 9733f11d16STom Herbert 9890bfe662STom Herbert static inline bool ila_csum_neutral_set(struct ila_identifier ident) 9990bfe662STom Herbert { 10090bfe662STom Herbert return !!(ident.csum_neutral); 10190bfe662STom Herbert } 10290bfe662STom Herbert 103707a2ca4STom Herbert void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p, 104707a2ca4STom Herbert bool set_csum_neutral); 10533f11d16STom Herbert 10690bfe662STom Herbert void ila_init_saved_csum(struct ila_params *p); 10790bfe662STom Herbert 108*ad68147eSTom Herbert struct ila_net { 109*ad68147eSTom Herbert struct { 110*ad68147eSTom Herbert struct rhashtable rhash_table; 111*ad68147eSTom Herbert spinlock_t *locks; /* Bucket locks for entry manipulation */ 112*ad68147eSTom Herbert unsigned int locks_mask; 113*ad68147eSTom Herbert bool hooks_registered; 114*ad68147eSTom Herbert } xlat; 115*ad68147eSTom Herbert }; 116*ad68147eSTom Herbert 11733f11d16STom Herbert int ila_lwt_init(void); 11833f11d16STom Herbert void ila_lwt_fini(void); 119*ad68147eSTom Herbert 120*ad68147eSTom Herbert int ila_xlat_init_net(struct net *net); 121*ad68147eSTom Herbert void ila_xlat_exit_net(struct net *net); 122*ad68147eSTom Herbert 123*ad68147eSTom Herbert int ila_xlat_nl_cmd_add_mapping(struct sk_buff *skb, struct genl_info *info); 124*ad68147eSTom Herbert int ila_xlat_nl_cmd_del_mapping(struct sk_buff *skb, struct genl_info *info); 125*ad68147eSTom Herbert int ila_xlat_nl_cmd_get_mapping(struct sk_buff *skb, struct genl_info *info); 126*ad68147eSTom Herbert int ila_xlat_nl_dump_start(struct netlink_callback *cb); 127*ad68147eSTom Herbert int ila_xlat_nl_dump_done(struct netlink_callback *cb); 128*ad68147eSTom Herbert int ila_xlat_nl_dump(struct sk_buff *skb, struct netlink_callback *cb); 129*ad68147eSTom Herbert 130*ad68147eSTom Herbert extern unsigned int ila_net_id; 131*ad68147eSTom Herbert 132*ad68147eSTom Herbert extern struct genl_family ila_nl_family; 13333f11d16STom Herbert 13433f11d16STom Herbert #endif /* __ILA_H */ 135