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 26*351596aaSTom Herbert struct ila_locator { 27*351596aaSTom Herbert union { 28*351596aaSTom Herbert __u8 v8[8]; 29*351596aaSTom Herbert __be16 v16[4]; 30*351596aaSTom Herbert __be32 v32[2]; 31*351596aaSTom Herbert __be64 v64; 32*351596aaSTom Herbert }; 33*351596aaSTom Herbert }; 34*351596aaSTom Herbert 35*351596aaSTom Herbert struct ila_identifier { 36*351596aaSTom Herbert union { 37*351596aaSTom Herbert struct { 38*351596aaSTom Herbert #if defined(__LITTLE_ENDIAN_BITFIELD) 39*351596aaSTom Herbert u8 __space:5; 40*351596aaSTom Herbert u8 type:3; 41*351596aaSTom Herbert #elif defined(__BIG_ENDIAN_BITFIELD) 42*351596aaSTom Herbert u8 type:3; 43*351596aaSTom Herbert u8 __space:5; 44*351596aaSTom Herbert #else 45*351596aaSTom Herbert #error "Adjust your <asm/byteorder.h> defines" 46*351596aaSTom Herbert #endif 47*351596aaSTom Herbert u8 __space2[7]; 48*351596aaSTom Herbert }; 49*351596aaSTom Herbert __u8 v8[8]; 50*351596aaSTom Herbert __be16 v16[4]; 51*351596aaSTom Herbert __be32 v32[2]; 52*351596aaSTom Herbert __be64 v64; 53*351596aaSTom Herbert }; 54*351596aaSTom Herbert }; 55*351596aaSTom Herbert 56*351596aaSTom Herbert enum { 57*351596aaSTom Herbert ILA_ATYPE_IID = 0, 58*351596aaSTom Herbert ILA_ATYPE_LUID, 59*351596aaSTom Herbert ILA_ATYPE_VIRT_V4, 60*351596aaSTom Herbert ILA_ATYPE_VIRT_UNI_V6, 61*351596aaSTom Herbert ILA_ATYPE_VIRT_MULTI_V6, 62*351596aaSTom Herbert ILA_ATYPE_RSVD_1, 63*351596aaSTom Herbert ILA_ATYPE_RSVD_2, 64*351596aaSTom Herbert ILA_ATYPE_RSVD_3, 65*351596aaSTom Herbert }; 66*351596aaSTom Herbert 67*351596aaSTom Herbert struct ila_addr { 68*351596aaSTom Herbert union { 69*351596aaSTom Herbert struct in6_addr addr; 70*351596aaSTom Herbert struct { 71*351596aaSTom Herbert struct ila_locator loc; 72*351596aaSTom Herbert struct ila_identifier ident; 73*351596aaSTom Herbert }; 74*351596aaSTom Herbert }; 75*351596aaSTom Herbert }; 76*351596aaSTom Herbert 77*351596aaSTom Herbert static inline struct ila_addr *ila_a2i(struct in6_addr *addr) 78*351596aaSTom Herbert { 79*351596aaSTom Herbert return (struct ila_addr *)addr; 80*351596aaSTom Herbert } 81*351596aaSTom Herbert 82*351596aaSTom Herbert static inline bool ila_addr_is_ila(struct ila_addr *iaddr) 83*351596aaSTom Herbert { 84*351596aaSTom Herbert return (iaddr->ident.type != ILA_ATYPE_IID); 85*351596aaSTom Herbert } 86*351596aaSTom Herbert 8733f11d16STom Herbert struct ila_params { 88*351596aaSTom Herbert struct ila_locator locator; 89*351596aaSTom Herbert struct ila_locator locator_match; 9033f11d16STom Herbert __wsum csum_diff; 9133f11d16STom Herbert }; 9233f11d16STom Herbert 9333f11d16STom Herbert static inline __wsum compute_csum_diff8(const __be32 *from, const __be32 *to) 9433f11d16STom Herbert { 9533f11d16STom Herbert __be32 diff[] = { 9633f11d16STom Herbert ~from[0], ~from[1], to[0], to[1], 9733f11d16STom Herbert }; 9833f11d16STom Herbert 9933f11d16STom Herbert return csum_partial(diff, sizeof(diff), 0); 10033f11d16STom Herbert } 10133f11d16STom Herbert 102*351596aaSTom Herbert void ila_update_ipv6_locator(struct sk_buff *skb, struct ila_params *p); 10333f11d16STom Herbert 10433f11d16STom Herbert int ila_lwt_init(void); 10533f11d16STom Herbert void ila_lwt_fini(void); 1067f00feafSTom Herbert int ila_xlat_init(void); 1077f00feafSTom Herbert void ila_xlat_fini(void); 10833f11d16STom Herbert 10933f11d16STom Herbert #endif /* __ILA_H */ 110