Linux Audio

Check our new training course

Loading...
v4.17
  1/*
  2 * xfrm4_mode_transport.c - Transport mode encapsulation for IPv4.
  3 *
  4 * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
  5 */
  6
  7#include <linux/init.h>
  8#include <linux/kernel.h>
  9#include <linux/module.h>
 10#include <linux/skbuff.h>
 11#include <linux/stringify.h>
 12#include <net/dst.h>
 13#include <net/ip.h>
 14#include <net/xfrm.h>
 15#include <net/protocol.h>
 16
 17/* Add encapsulation header.
 18 *
 19 * The IP header will be moved forward to make space for the encapsulation
 20 * header.
 21 */
 22static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb)
 23{
 24	struct iphdr *iph = ip_hdr(skb);
 25	int ihl = iph->ihl * 4;
 26
 27	skb_set_inner_transport_header(skb, skb_transport_offset(skb));
 28
 29	skb_set_network_header(skb, -x->props.header_len);
 30	skb->mac_header = skb->network_header +
 31			  offsetof(struct iphdr, protocol);
 32	skb->transport_header = skb->network_header + ihl;
 33	__skb_pull(skb, ihl);
 34	memmove(skb_network_header(skb), iph, ihl);
 35	return 0;
 36}
 37
 38/* Remove encapsulation header.
 39 *
 40 * The IP header will be moved over the top of the encapsulation header.
 41 *
 42 * On entry, skb->h shall point to where the IP header should be and skb->nh
 43 * shall be set to where the IP header currently is.  skb->data shall point
 44 * to the start of the payload.
 45 */
 46static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
 47{
 48	int ihl = skb->data - skb_transport_header(skb);
 49	struct xfrm_offload *xo = xfrm_offload(skb);
 50
 51	if (skb->transport_header != skb->network_header) {
 52		memmove(skb_transport_header(skb),
 53			skb_network_header(skb), ihl);
 54		skb->network_header = skb->transport_header;
 55	}
 56	ip_hdr(skb)->tot_len = htons(skb->len + ihl);
 57	if (!xo || !(xo->flags & XFRM_GRO))
 58		skb_reset_transport_header(skb);
 59	return 0;
 60}
 61
 62static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
 63						   struct sk_buff *skb,
 64						   netdev_features_t features)
 65{
 66	const struct net_offload *ops;
 67	struct sk_buff *segs = ERR_PTR(-EINVAL);
 68	struct xfrm_offload *xo = xfrm_offload(skb);
 69
 70	skb->transport_header += x->props.header_len;
 71	ops = rcu_dereference(inet_offloads[xo->proto]);
 72	if (likely(ops && ops->callbacks.gso_segment))
 73		segs = ops->callbacks.gso_segment(skb, features);
 74
 75	return segs;
 76}
 77
 78static void xfrm4_transport_xmit(struct xfrm_state *x, struct sk_buff *skb)
 79{
 80	struct xfrm_offload *xo = xfrm_offload(skb);
 81
 82	skb_reset_mac_len(skb);
 83	pskb_pull(skb, skb->mac_len + sizeof(struct iphdr) + x->props.header_len);
 84
 85	if (xo->flags & XFRM_GSO_SEGMENT) {
 86		 skb_reset_transport_header(skb);
 87		 skb->transport_header -= x->props.header_len;
 88	}
 89}
 90
 91static struct xfrm_mode xfrm4_transport_mode = {
 92	.input = xfrm4_transport_input,
 93	.output = xfrm4_transport_output,
 94	.gso_segment = xfrm4_transport_gso_segment,
 95	.xmit = xfrm4_transport_xmit,
 96	.owner = THIS_MODULE,
 97	.encap = XFRM_MODE_TRANSPORT,
 98};
 99
100static int __init xfrm4_transport_init(void)
101{
102	return xfrm_register_mode(&xfrm4_transport_mode, AF_INET);
103}
104
105static void __exit xfrm4_transport_exit(void)
106{
107	int err;
108
109	err = xfrm_unregister_mode(&xfrm4_transport_mode, AF_INET);
110	BUG_ON(err);
111}
112
113module_init(xfrm4_transport_init);
114module_exit(xfrm4_transport_exit);
115MODULE_LICENSE("GPL");
116MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TRANSPORT);
v3.15
 1/*
 2 * xfrm4_mode_transport.c - Transport mode encapsulation for IPv4.
 3 *
 4 * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au>
 5 */
 6
 7#include <linux/init.h>
 8#include <linux/kernel.h>
 9#include <linux/module.h>
10#include <linux/skbuff.h>
11#include <linux/stringify.h>
12#include <net/dst.h>
13#include <net/ip.h>
14#include <net/xfrm.h>
 
15
16/* Add encapsulation header.
17 *
18 * The IP header will be moved forward to make space for the encapsulation
19 * header.
20 */
21static int xfrm4_transport_output(struct xfrm_state *x, struct sk_buff *skb)
22{
23	struct iphdr *iph = ip_hdr(skb);
24	int ihl = iph->ihl * 4;
25
 
 
26	skb_set_network_header(skb, -x->props.header_len);
27	skb->mac_header = skb->network_header +
28			  offsetof(struct iphdr, protocol);
29	skb->transport_header = skb->network_header + ihl;
30	__skb_pull(skb, ihl);
31	memmove(skb_network_header(skb), iph, ihl);
32	return 0;
33}
34
35/* Remove encapsulation header.
36 *
37 * The IP header will be moved over the top of the encapsulation header.
38 *
39 * On entry, skb->h shall point to where the IP header should be and skb->nh
40 * shall be set to where the IP header currently is.  skb->data shall point
41 * to the start of the payload.
42 */
43static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
44{
45	int ihl = skb->data - skb_transport_header(skb);
 
46
47	if (skb->transport_header != skb->network_header) {
48		memmove(skb_transport_header(skb),
49			skb_network_header(skb), ihl);
50		skb->network_header = skb->transport_header;
51	}
52	ip_hdr(skb)->tot_len = htons(skb->len + ihl);
53	skb_reset_transport_header(skb);
 
54	return 0;
55}
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57static struct xfrm_mode xfrm4_transport_mode = {
58	.input = xfrm4_transport_input,
59	.output = xfrm4_transport_output,
 
 
60	.owner = THIS_MODULE,
61	.encap = XFRM_MODE_TRANSPORT,
62};
63
64static int __init xfrm4_transport_init(void)
65{
66	return xfrm_register_mode(&xfrm4_transport_mode, AF_INET);
67}
68
69static void __exit xfrm4_transport_exit(void)
70{
71	int err;
72
73	err = xfrm_unregister_mode(&xfrm4_transport_mode, AF_INET);
74	BUG_ON(err);
75}
76
77module_init(xfrm4_transport_init);
78module_exit(xfrm4_transport_exit);
79MODULE_LICENSE("GPL");
80MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TRANSPORT);