1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #include <linux/ipv6.h> 3 #include <net/dsfield.h> 4 #include <net/xfrm.h> 5 6 #ifndef XFRM_INOUT_H 7 #define XFRM_INOUT_H 1 8 9 static inline void xfrm4_extract_header(struct sk_buff *skb) 10 { 11 const struct iphdr *iph = ip_hdr(skb); 12 13 XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph); 14 XFRM_MODE_SKB_CB(skb)->id = iph->id; 15 XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off; 16 XFRM_MODE_SKB_CB(skb)->tos = iph->tos; 17 XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl; 18 XFRM_MODE_SKB_CB(skb)->optlen = iph->ihl * 4 - sizeof(*iph); 19 memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0, 20 sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); 21 } 22 23 static inline void xfrm6_extract_header(struct sk_buff *skb) 24 { 25 #if IS_ENABLED(CONFIG_IPV6) 26 struct ipv6hdr *iph = ipv6_hdr(skb); 27 28 XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph); 29 XFRM_MODE_SKB_CB(skb)->id = 0; 30 XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF); 31 XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph); 32 XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit; 33 XFRM_MODE_SKB_CB(skb)->optlen = 0; 34 memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl, 35 sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); 36 #else 37 WARN_ON_ONCE(1); 38 #endif 39 } 40 41 static inline void xfrm6_beet_make_header(struct sk_buff *skb) 42 { 43 struct ipv6hdr *iph = ipv6_hdr(skb); 44 45 iph->version = 6; 46 47 memcpy(iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl, 48 sizeof(iph->flow_lbl)); 49 iph->nexthdr = XFRM_MODE_SKB_CB(skb)->protocol; 50 51 ipv6_change_dsfield(iph, 0, XFRM_MODE_SKB_CB(skb)->tos); 52 iph->hop_limit = XFRM_MODE_SKB_CB(skb)->ttl; 53 } 54 55 static inline void xfrm4_beet_make_header(struct sk_buff *skb) 56 { 57 struct iphdr *iph = ip_hdr(skb); 58 59 iph->ihl = 5; 60 iph->version = 4; 61 62 iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol; 63 iph->tos = XFRM_MODE_SKB_CB(skb)->tos; 64 65 iph->id = XFRM_MODE_SKB_CB(skb)->id; 66 iph->frag_off = XFRM_MODE_SKB_CB(skb)->frag_off; 67 iph->ttl = XFRM_MODE_SKB_CB(skb)->ttl; 68 } 69 70 #endif 71