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> 2233f11d16STom Herbert #include <net/ip.h> 2333f11d16STom Herbert #include <net/protocol.h> 2433f11d16STom Herbert #include <uapi/linux/ila.h> 2533f11d16STom Herbert 26351596aaSTom Herbert struct ila_locator { 27351596aaSTom Herbert union { 28351596aaSTom Herbert __u8 v8[8]; 29351596aaSTom Herbert __be16 v16[4]; 30351596aaSTom Herbert __be32 v32[2]; 31351596aaSTom Herbert __be64 v64; 32351596aaSTom Herbert }; 33351596aaSTom Herbert }; 34351596aaSTom Herbert 35351596aaSTom Herbert struct ila_identifier { 36351596aaSTom Herbert union { 37351596aaSTom Herbert struct { 38351596aaSTom Herbert #if defined(__LITTLE_ENDIAN_BITFIELD) 3990bfe662STom Herbert u8 __space:4; 4090bfe662STom Herbert u8 csum_neutral:1; 41351596aaSTom Herbert u8 type:3; 42351596aaSTom Herbert #elif defined(__BIG_ENDIAN_BITFIELD) 43351596aaSTom Herbert u8 type:3; 4490bfe662STom Herbert u8 csum_neutral:1; 4590bfe662STom Herbert u8 __space:4; 46351596aaSTom Herbert #else 47351596aaSTom Herbert #error "Adjust your <asm/byteorder.h> defines" 48351596aaSTom Herbert #endif 49351596aaSTom Herbert u8 __space2[7]; 50351596aaSTom Herbert }; 51351596aaSTom Herbert __u8 v8[8]; 52351596aaSTom Herbert __be16 v16[4]; 53351596aaSTom Herbert __be32 v32[2]; 54351596aaSTom Herbert __be64 v64; 55351596aaSTom Herbert }; 56351596aaSTom Herbert }; 57351596aaSTom Herbert 5890bfe662STom Herbert #define CSUM_NEUTRAL_FLAG htonl(0x10000000) 5990bfe662STom Herbert 60351596aaSTom Herbert struct ila_addr { 61351596aaSTom Herbert union { 62351596aaSTom Herbert struct in6_addr addr; 63351596aaSTom Herbert struct { 64351596aaSTom Herbert struct ila_locator loc; 65351596aaSTom Herbert struct ila_identifier ident; 66351596aaSTom Herbert }; 67351596aaSTom Herbert }; 68351596aaSTom Herbert }; 69351596aaSTom Herbert 70351596aaSTom Herbert static inline struct ila_addr *ila_a2i(struct in6_addr *addr) 71351596aaSTom Herbert { 72351596aaSTom Herbert return (struct ila_addr *)addr; 73351596aaSTom Herbert } 74351596aaSTom Herbert 75351596aaSTom Herbert static inline bool ila_addr_is_ila(struct ila_addr *iaddr) 76351596aaSTom Herbert { 77351596aaSTom Herbert return (iaddr->ident.type != ILA_ATYPE_IID); 78351596aaSTom Herbert } 79351596aaSTom Herbert 8033f11d16STom Herbert struct ila_params { 81351596aaSTom Herbert struct ila_locator locator; 82351596aaSTom Herbert struct ila_locator locator_match; 8333f11d16STom Herbert __wsum csum_diff; 8490bfe662STom Herbert u8 csum_mode; 85*70d5aef4STom Herbert u8 ident_type; 8633f11d16STom Herbert }; 8733f11d16STom Herbert 8833f11d16STom Herbert static inline __wsum compute_csum_diff8(const __be32 *from, const __be32 *to) 8933f11d16STom Herbert { 9033f11d16STom Herbert __be32 diff[] = { 9133f11d16STom Herbert ~from[0], ~from[1], to[0], to[1], 9233f11d16STom Herbert }; 9333f11d16STom Herbert 9433f11d16STom Herbert return csum_partial(diff, sizeof(diff), 0); 9533f11d16STom Herbert } 9633f11d16STom Herbert 9790bfe662STom Herbert static inline bool ila_csum_neutral_set(struct ila_identifier ident) 9890bfe662STom Herbert { 9990bfe662STom Herbert return !!(ident.csum_neutral); 10090bfe662STom Herbert } 10190bfe662STom Herbert 102707a2ca4STom Herbert void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p, 103707a2ca4STom Herbert bool set_csum_neutral); 10433f11d16STom Herbert 10590bfe662STom Herbert void ila_init_saved_csum(struct ila_params *p); 10690bfe662STom Herbert 10733f11d16STom Herbert int ila_lwt_init(void); 10833f11d16STom Herbert void ila_lwt_fini(void); 1097f00feafSTom Herbert int ila_xlat_init(void); 1107f00feafSTom Herbert void ila_xlat_fini(void); 11133f11d16STom Herbert 11233f11d16STom Herbert #endif /* __ILA_H */ 113