12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 21ababebaSDavid Lebrun /* 31ababebaSDavid Lebrun * SR-IPv6 implementation 41ababebaSDavid Lebrun * 51ababebaSDavid Lebrun * Author: 61ababebaSDavid Lebrun * David Lebrun <david.lebrun@uclouvain.be> 71ababebaSDavid Lebrun */ 81ababebaSDavid Lebrun 91ababebaSDavid Lebrun #ifndef _NET_SEG6_H 101ababebaSDavid Lebrun #define _NET_SEG6_H 111ababebaSDavid Lebrun 12915d7e5eSDavid Lebrun #include <linux/net.h> 13915d7e5eSDavid Lebrun #include <linux/ipv6.h> 146c8702c6SDavid Lebrun #include <linux/seg6.h> 150eb71a9dSNeilBrown #include <linux/rhashtable-types.h> 16915d7e5eSDavid Lebrun 171ababebaSDavid Lebrun static inline void update_csum_diff4(struct sk_buff *skb, __be32 from, 181ababebaSDavid Lebrun __be32 to) 191ababebaSDavid Lebrun { 201ababebaSDavid Lebrun __be32 diff[] = { ~from, to }; 211ababebaSDavid Lebrun 221ababebaSDavid Lebrun skb->csum = ~csum_partial((char *)diff, sizeof(diff), ~skb->csum); 231ababebaSDavid Lebrun } 241ababebaSDavid Lebrun 251ababebaSDavid Lebrun static inline void update_csum_diff16(struct sk_buff *skb, __be32 *from, 261ababebaSDavid Lebrun __be32 *to) 271ababebaSDavid Lebrun { 281ababebaSDavid Lebrun __be32 diff[] = { 291ababebaSDavid Lebrun ~from[0], ~from[1], ~from[2], ~from[3], 301ababebaSDavid Lebrun to[0], to[1], to[2], to[3], 311ababebaSDavid Lebrun }; 321ababebaSDavid Lebrun 331ababebaSDavid Lebrun skb->csum = ~csum_partial((char *)diff, sizeof(diff), ~skb->csum); 341ababebaSDavid Lebrun } 351ababebaSDavid Lebrun 36915d7e5eSDavid Lebrun struct seg6_pernet_data { 37915d7e5eSDavid Lebrun struct mutex lock; 38915d7e5eSDavid Lebrun struct in6_addr __rcu *tun_src; 39bf355b8dSDavid Lebrun #ifdef CONFIG_IPV6_SEG6_HMAC 40bf355b8dSDavid Lebrun struct rhashtable hmac_infos; 41bf355b8dSDavid Lebrun #endif 42915d7e5eSDavid Lebrun }; 43915d7e5eSDavid Lebrun 44915d7e5eSDavid Lebrun static inline struct seg6_pernet_data *seg6_pernet(struct net *net) 45915d7e5eSDavid Lebrun { 4663526e1cSMathieu Xhonneux #if IS_ENABLED(CONFIG_IPV6) 47915d7e5eSDavid Lebrun return net->ipv6.seg6_data; 4863526e1cSMathieu Xhonneux #else 4963526e1cSMathieu Xhonneux return NULL; 5063526e1cSMathieu Xhonneux #endif 51915d7e5eSDavid Lebrun } 52915d7e5eSDavid Lebrun 53915d7e5eSDavid Lebrun extern int seg6_init(void); 54915d7e5eSDavid Lebrun extern void seg6_exit(void); 556c8702c6SDavid Lebrun extern int seg6_iptunnel_init(void); 566c8702c6SDavid Lebrun extern void seg6_iptunnel_exit(void); 57d1df6fd8SDavid Lebrun extern int seg6_local_init(void); 58d1df6fd8SDavid Lebrun extern void seg6_local_exit(void); 596c8702c6SDavid Lebrun 60bb986a50SAhmed Abdelsalam extern bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len, bool reduced); 61*85b3b307SAndrew Lunn extern struct ipv6_sr_hdr *seg6_get_srh(struct sk_buff *skb, int flags); 6232d99d0bSDavid Lebrun extern int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, 6332d99d0bSDavid Lebrun int proto); 64b04c80d3SDavid Lebrun extern int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh); 651c1e761eSMathieu Xhonneux extern int seg6_lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr, 661c1e761eSMathieu Xhonneux u32 tbl_id); 671ababebaSDavid Lebrun #endif 68