12 #include <linux/kernel.h>
14 #include <linux/if_tunnel.h>
28 memset(fl4, 0,
sizeof(*fl4));
30 fl4->flowi4_tos = tos;
41 static struct dst_entry *xfrm4_dst_lookup(
struct net *net,
int tos,
47 return __xfrm4_dst_lookup(net, &fl4, tos, saddr, daddr);
50 static int xfrm4_get_saddr(
struct net *net,
56 dst = __xfrm4_dst_lookup(net, &fl4, 0,
NULL, daddr);
65 static int xfrm4_get_tos(
const struct flowi *
fl)
82 xdst->
u.
rt.rt_iif = fl4->flowi4_iif;
84 xdst->
u.
dst.dev = dev;
96 INIT_LIST_HEAD(&xdst->
u.
rt.rt_uncached);
104 const struct iphdr *iph = ip_hdr(skb);
105 u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
109 fl4->flowi4_mark = skb->
mark;
111 if (!ip_is_fragment(iph)) {
118 if (xprth + 4 < skb->
data ||
119 pskb_may_pull(skb, xprth + 4 - skb->
data)) {
122 fl4->fl4_sport = ports[!!reverse];
123 fl4->fl4_dport = ports[!reverse];
128 if (pskb_may_pull(skb, xprth + 2 - skb->
data)) {
131 fl4->fl4_icmp_type = icmp[0];
132 fl4->fl4_icmp_code = icmp[1];
137 if (pskb_may_pull(skb, xprth + 4 - skb->
data)) {
140 fl4->fl4_ipsec_spi = ehdr[0];
145 if (pskb_may_pull(skb, xprth + 8 - skb->
data)) {
148 fl4->fl4_ipsec_spi = ah_hdr[1];
153 if (pskb_may_pull(skb, xprth + 4 - skb->
data)) {
156 fl4->fl4_ipsec_spi =
htonl(
ntohs(ipcomp_hdr[1]));
161 if (pskb_may_pull(skb, xprth + 12 - skb->
data)) {
168 fl4->fl4_gre_key = gre_hdr[1];
174 fl4->fl4_ipsec_spi = 0;
181 fl4->flowi4_tos = iph->
tos;
184 static inline int xfrm4_garbage_collect(
struct dst_ops *ops)
186 struct net *net =
container_of(ops,
struct net, xfrm.xfrm4_dst_ops);
188 xfrm4_policy_afinfo.garbage_collect(net);
189 return (dst_entries_get_slow(ops) > ops->
gc_thresh * 2);
198 path->
ops->update_pmtu(path, sk, skb, mtu);
201 static void xfrm4_redirect(
struct dst_entry *dst,
struct sock *sk,
207 path->
ops->redirect(path, sk, skb);
210 static void xfrm4_dst_destroy(
struct dst_entry *dst)
214 dst_destroy_metrics_generic(dst);
216 xfrm_dst_destroy(xdst);
228 static struct dst_ops xfrm4_dst_ops = {
231 .gc = xfrm4_garbage_collect,
232 .update_pmtu = xfrm4_update_pmtu,
233 .redirect = xfrm4_redirect,
235 .destroy = xfrm4_dst_destroy,
236 .ifdown = xfrm4_dst_ifdown,
243 .dst_ops = &xfrm4_dst_ops,
244 .dst_lookup = xfrm4_dst_lookup,
245 .get_saddr = xfrm4_get_saddr,
246 .decode_session = _decode_session4,
247 .get_tos = xfrm4_get_tos,
248 .init_path = xfrm4_init_path,
249 .fill_dst = xfrm4_fill_dst,
254 static struct ctl_table xfrm4_policy_table[] = {
257 .data = &
init_net.xfrm.xfrm4_dst_ops.gc_thresh,
258 .maxlen =
sizeof(
int),
268 static void __init xfrm4_policy_init(
void)
273 static void __exit xfrm4_policy_fini(
void)
284 dst_entries_init(&xfrm4_dst_ops);