Blame view
net/ipv4/ipcomp.c
4.64 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 |
/* * IP Payload Compression Protocol (IPComp) - RFC3173. * * Copyright (c) 2003 James Morris <jmorris@intercode.com.au> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free |
e905a9eda [NET] IPV4: Fix w... |
8 |
* Software Foundation; either version 2 of the License, or (at your option) |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 12 13 14 15 |
* any later version. * * Todo: * - Tunable compression parameters. * - Compression stats. * - Adaptive compression. */ |
1da177e4c Linux-2.6.12-rc2 |
16 |
#include <linux/module.h> |
4999f3621 [IPSEC]: Fix cryp... |
17 |
#include <linux/err.h> |
1da177e4c Linux-2.6.12-rc2 |
18 19 20 21 22 |
#include <linux/rtnetlink.h> #include <net/ip.h> #include <net/xfrm.h> #include <net/icmp.h> #include <net/ipcomp.h> |
14c850212 [INET_SOCK]: Move... |
23 |
#include <net/protocol.h> |
6fccab671 ipsec: ipcomp - M... |
24 |
#include <net/sock.h> |
1da177e4c Linux-2.6.12-rc2 |
25 |
|
d099160e0 ipcomp4: Use the ... |
26 |
static int ipcomp4_err(struct sk_buff *skb, u32 info) |
1da177e4c Linux-2.6.12-rc2 |
27 |
{ |
a92df2545 netns xfrm: ipcom... |
28 |
struct net *net = dev_net(skb->dev); |
a94cfd197 [XFRM]: xfrm_stat... |
29 |
__be32 spi; |
b71d1d426 inet: constify ip... |
30 |
const struct iphdr *iph = (const struct iphdr *)skb->data; |
1da177e4c Linux-2.6.12-rc2 |
31 32 |
struct ip_comp_hdr *ipch = (struct ip_comp_hdr *)(skb->data+(iph->ihl<<2)); struct xfrm_state *x; |
55be7a9c6 ipv4: Add redirec... |
33 34 35 |
switch (icmp_hdr(skb)->type) { case ICMP_DEST_UNREACH: if (icmp_hdr(skb)->code != ICMP_FRAG_NEEDED) |
d099160e0 ipcomp4: Use the ... |
36 |
return 0; |
55be7a9c6 ipv4: Add redirec... |
37 38 39 |
case ICMP_REDIRECT: break; default: |
d099160e0 ipcomp4: Use the ... |
40 |
return 0; |
55be7a9c6 ipv4: Add redirec... |
41 |
} |
1da177e4c Linux-2.6.12-rc2 |
42 |
|
4195f8145 [NET]: Fix "ntohl... |
43 |
spi = htonl(ntohs(ipch->cpi)); |
b71d1d426 inet: constify ip... |
44 |
x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr, |
e905a9eda [NET] IPV4: Fix w... |
45 |
spi, IPPROTO_COMP, AF_INET); |
1da177e4c Linux-2.6.12-rc2 |
46 |
if (!x) |
d099160e0 ipcomp4: Use the ... |
47 |
return 0; |
55be7a9c6 ipv4: Add redirec... |
48 |
|
387aa65a8 ipv4: properly re... |
49 |
if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH) |
55be7a9c6 ipv4: Add redirec... |
50 |
ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_COMP, 0); |
387aa65a8 ipv4: properly re... |
51 |
else |
55be7a9c6 ipv4: Add redirec... |
52 |
ipv4_redirect(skb, net, 0, 0, IPPROTO_COMP, 0); |
1da177e4c Linux-2.6.12-rc2 |
53 |
xfrm_state_put(x); |
d099160e0 ipcomp4: Use the ... |
54 55 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
56 |
} |
e905a9eda [NET] IPV4: Fix w... |
57 |
/* We always hold one tunnel user reference to indicate a tunnel */ |
1da177e4c Linux-2.6.12-rc2 |
58 59 |
static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x) { |
a92df2545 netns xfrm: ipcom... |
60 |
struct net *net = xs_net(x); |
1da177e4c Linux-2.6.12-rc2 |
61 |
struct xfrm_state *t; |
e905a9eda [NET] IPV4: Fix w... |
62 |
|
a92df2545 netns xfrm: ipcom... |
63 |
t = xfrm_state_alloc(net); |
51456b291 ipv4: coding styl... |
64 |
if (!t) |
1da177e4c Linux-2.6.12-rc2 |
65 66 67 68 69 70 71 |
goto out; t->id.proto = IPPROTO_IPIP; t->id.spi = x->props.saddr.a4; t->id.daddr.a4 = x->id.daddr.a4; memcpy(&t->sel, &x->sel, sizeof(t->sel)); t->props.family = AF_INET; |
e40b32861 [IPSEC]: Forbid B... |
72 |
t->props.mode = x->props.mode; |
1da177e4c Linux-2.6.12-rc2 |
73 74 |
t->props.saddr.a4 = x->props.saddr.a4; t->props.flags = x->props.flags; |
a947b0a93 xfrm: allow to av... |
75 |
t->props.extra_flags = x->props.extra_flags; |
bd55775c8 xfrm: SA lookups ... |
76 |
memcpy(&t->mark, &x->mark, sizeof(t->mark)); |
72cb6962a [IPSEC]: Add xfrm... |
77 78 |
if (xfrm_init_state(t)) |
1da177e4c Linux-2.6.12-rc2 |
79 |
goto error; |
1da177e4c Linux-2.6.12-rc2 |
80 81 82 83 84 85 86 87 88 89 90 91 |
atomic_set(&t->tunnel_users, 1); out: return t; error: t->km.state = XFRM_STATE_DEAD; xfrm_state_put(t); t = NULL; goto out; } /* |
4a3e2f711 [NET] sem2mutex: ... |
92 |
* Must be protected by xfrm_cfg_mutex. State and tunnel user references are |
1da177e4c Linux-2.6.12-rc2 |
93 94 95 96 |
* always incremented on success. */ static int ipcomp_tunnel_attach(struct xfrm_state *x) { |
a92df2545 netns xfrm: ipcom... |
97 |
struct net *net = xs_net(x); |
1da177e4c Linux-2.6.12-rc2 |
98 99 |
int err = 0; struct xfrm_state *t; |
bd55775c8 xfrm: SA lookups ... |
100 |
u32 mark = x->mark.v & x->mark.m; |
1da177e4c Linux-2.6.12-rc2 |
101 |
|
bd55775c8 xfrm: SA lookups ... |
102 |
t = xfrm_state_lookup(net, mark, (xfrm_address_t *)&x->id.daddr.a4, |
e905a9eda [NET] IPV4: Fix w... |
103 |
x->props.saddr.a4, IPPROTO_IPIP, AF_INET); |
1da177e4c Linux-2.6.12-rc2 |
104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
if (!t) { t = ipcomp_tunnel_create(x); if (!t) { err = -EINVAL; goto out; } xfrm_state_insert(t); xfrm_state_hold(t); } x->tunnel = t; atomic_inc(&t->tunnel_users); out: return err; } |
6fccab671 ipsec: ipcomp - M... |
118 |
static int ipcomp4_init_state(struct xfrm_state *x) |
1da177e4c Linux-2.6.12-rc2 |
119 |
{ |
2c3abab7c ipcomp: Fix warni... |
120 |
int err = -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
121 |
|
e40b32861 [IPSEC]: Forbid B... |
122 123 124 125 126 127 128 129 130 131 |
x->props.header_len = 0; switch (x->props.mode) { case XFRM_MODE_TRANSPORT: break; case XFRM_MODE_TUNNEL: x->props.header_len += sizeof(struct iphdr); break; default: goto out; } |
6fccab671 ipsec: ipcomp - M... |
132 133 |
err = ipcomp_init_state(x); if (err) |
1da177e4c Linux-2.6.12-rc2 |
134 |
goto out; |
7e49e6de3 [XFRM]: Add XFRM_... |
135 |
if (x->props.mode == XFRM_MODE_TUNNEL) { |
1da177e4c Linux-2.6.12-rc2 |
136 137 |
err = ipcomp_tunnel_attach(x); if (err) |
10e7454ed ipcomp: Avoid dup... |
138 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
139 |
} |
1da177e4c Linux-2.6.12-rc2 |
140 141 142 |
err = 0; out: return err; |
1da177e4c Linux-2.6.12-rc2 |
143 |
} |
d099160e0 ipcomp4: Use the ... |
144 145 146 147 |
static int ipcomp4_rcv_cb(struct sk_buff *skb, int err) { return 0; } |
533cb5b0a [XFRM]: constify ... |
148 |
static const struct xfrm_type ipcomp_type = { |
1da177e4c Linux-2.6.12-rc2 |
149 150 151 |
.description = "IPCOMP4", .owner = THIS_MODULE, .proto = IPPROTO_COMP, |
6fccab671 ipsec: ipcomp - M... |
152 |
.init_state = ipcomp4_init_state, |
1da177e4c Linux-2.6.12-rc2 |
153 154 155 156 |
.destructor = ipcomp_destroy, .input = ipcomp_input, .output = ipcomp_output }; |
d099160e0 ipcomp4: Use the ... |
157 |
static struct xfrm4_protocol ipcomp4_protocol = { |
1da177e4c Linux-2.6.12-rc2 |
158 |
.handler = xfrm4_rcv, |
d099160e0 ipcomp4: Use the ... |
159 160 |
.input_handler = xfrm_input, .cb_handler = ipcomp4_rcv_cb, |
1da177e4c Linux-2.6.12-rc2 |
161 |
.err_handler = ipcomp4_err, |
d099160e0 ipcomp4: Use the ... |
162 |
.priority = 0, |
1da177e4c Linux-2.6.12-rc2 |
163 164 165 166 167 |
}; static int __init ipcomp4_init(void) { if (xfrm_register_type(&ipcomp_type, AF_INET) < 0) { |
058bd4d2a net: Convert prin... |
168 169 |
pr_info("%s: can't add xfrm type ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
170 171 |
return -EAGAIN; } |
d099160e0 ipcomp4: Use the ... |
172 |
if (xfrm4_protocol_register(&ipcomp4_protocol, IPPROTO_COMP) < 0) { |
058bd4d2a net: Convert prin... |
173 174 |
pr_info("%s: can't add protocol ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
175 176 177 178 179 180 181 182 |
xfrm_unregister_type(&ipcomp_type, AF_INET); return -EAGAIN; } return 0; } static void __exit ipcomp4_fini(void) { |
d099160e0 ipcomp4: Use the ... |
183 |
if (xfrm4_protocol_deregister(&ipcomp4_protocol, IPPROTO_COMP) < 0) |
058bd4d2a net: Convert prin... |
184 185 |
pr_info("%s: can't remove protocol ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
186 |
if (xfrm_unregister_type(&ipcomp_type, AF_INET) < 0) |
058bd4d2a net: Convert prin... |
187 188 |
pr_info("%s: can't remove xfrm type ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
189 190 191 192 193 194 |
} module_init(ipcomp4_init); module_exit(ipcomp4_fini); MODULE_LICENSE("GPL"); |
6fccab671 ipsec: ipcomp - M... |
195 |
MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp/IPv4) - RFC3173"); |
1da177e4c Linux-2.6.12-rc2 |
196 |
MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); |
d3d6dd3ad [XFRM]: Add modul... |
197 |
MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_COMP); |