xref: /openbmc/linux/include/net/seg6.h (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1  /* SPDX-License-Identifier: GPL-2.0-or-later */
2  /*
3   *  SR-IPv6 implementation
4   *
5   *  Author:
6   *  David Lebrun <david.lebrun@uclouvain.be>
7   */
8  
9  #ifndef _NET_SEG6_H
10  #define _NET_SEG6_H
11  
12  #include <linux/net.h>
13  #include <linux/ipv6.h>
14  #include <linux/seg6.h>
15  #include <linux/rhashtable-types.h>
16  
update_csum_diff4(struct sk_buff * skb,__be32 from,__be32 to)17  static inline void update_csum_diff4(struct sk_buff *skb, __be32 from,
18  				     __be32 to)
19  {
20  	__be32 diff[] = { ~from, to };
21  
22  	skb->csum = ~csum_partial((char *)diff, sizeof(diff), ~skb->csum);
23  }
24  
update_csum_diff16(struct sk_buff * skb,__be32 * from,__be32 * to)25  static inline void update_csum_diff16(struct sk_buff *skb, __be32 *from,
26  				      __be32 *to)
27  {
28  	__be32 diff[] = {
29  		~from[0], ~from[1], ~from[2], ~from[3],
30  		to[0], to[1], to[2], to[3],
31  	};
32  
33  	skb->csum = ~csum_partial((char *)diff, sizeof(diff), ~skb->csum);
34  }
35  
36  struct seg6_pernet_data {
37  	struct mutex lock;
38  	struct in6_addr __rcu *tun_src;
39  #ifdef CONFIG_IPV6_SEG6_HMAC
40  	struct rhashtable hmac_infos;
41  #endif
42  };
43  
seg6_pernet(struct net * net)44  static inline struct seg6_pernet_data *seg6_pernet(struct net *net)
45  {
46  #if IS_ENABLED(CONFIG_IPV6)
47  	return net->ipv6.seg6_data;
48  #else
49  	return NULL;
50  #endif
51  }
52  
53  extern int seg6_init(void);
54  extern void seg6_exit(void);
55  extern int seg6_iptunnel_init(void);
56  extern void seg6_iptunnel_exit(void);
57  extern int seg6_local_init(void);
58  extern void seg6_local_exit(void);
59  
60  extern bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len, bool reduced);
61  extern struct ipv6_sr_hdr *seg6_get_srh(struct sk_buff *skb, int flags);
62  extern void seg6_icmp_srh(struct sk_buff *skb, struct inet6_skb_parm *opt);
63  extern int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh,
64  			     int proto);
65  extern int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh);
66  extern int seg6_lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
67  			       u32 tbl_id);
68  
69  /* If the packet which invoked an ICMP error contains an SRH return
70   * the true destination address from within the SRH, otherwise use the
71   * destination address in the IP header.
72   */
seg6_get_daddr(struct sk_buff * skb,struct inet6_skb_parm * opt)73  static inline const struct in6_addr *seg6_get_daddr(struct sk_buff *skb,
74  						    struct inet6_skb_parm *opt)
75  {
76  	struct ipv6_sr_hdr *srh;
77  
78  	if (opt->flags & IP6SKB_SEG6) {
79  		srh = (struct ipv6_sr_hdr *)(skb->data + opt->srhoff);
80  		return  &srh->segments[0];
81  	}
82  
83  	return NULL;
84  }
85  
86  
87  #endif
88