Blame view
net/ipv4/xfrm4_policy.c
5.93 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
e905a9eda [NET] IPV4: Fix w... |
2 |
/* |
1da177e4c Linux-2.6.12-rc2 |
3 4 5 6 7 8 |
* xfrm4_policy.c * * Changes: * Kazunori MIYAZAWA @USAGI * YOSHIFUJI Hideaki @USAGI * Split up af-specific portion |
e905a9eda [NET] IPV4: Fix w... |
9 |
* |
1da177e4c Linux-2.6.12-rc2 |
10 |
*/ |
66cdb3ca2 [IPSEC]: Move flo... |
11 12 |
#include <linux/err.h> #include <linux/kernel.h> |
aabc9761b [IPSEC]: Store id... |
13 |
#include <linux/inetdevice.h> |
45ff5a3f9 [IPSEC]: Set dst-... |
14 |
#include <net/dst.h> |
1da177e4c Linux-2.6.12-rc2 |
15 16 |
#include <net/xfrm.h> #include <net/ip.h> |
385add906 net: Replace vrf_... |
17 |
#include <net/l3mdev.h> |
1da177e4c Linux-2.6.12-rc2 |
18 |
|
8f01cb082 ipv4: xfrm: Elimi... |
19 |
static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4, |
42a7b32b7 xfrm: Add oif to ... |
20 |
int tos, int oif, |
8f01cb082 ipv4: xfrm: Elimi... |
21 |
const xfrm_address_t *saddr, |
077fbac40 net: xfrm: suppor... |
22 23 |
const xfrm_address_t *daddr, u32 mark) |
1da177e4c Linux-2.6.12-rc2 |
24 |
{ |
66cdb3ca2 [IPSEC]: Move flo... |
25 |
struct rtable *rt; |
a1e59abf8 [XFRM]: Fix wildc... |
26 |
|
8f01cb082 ipv4: xfrm: Elimi... |
27 28 29 |
memset(fl4, 0, sizeof(*fl4)); fl4->daddr = daddr->a4; fl4->flowi4_tos = tos; |
11d7a0bb9 xfrm: Only add l3... |
30 |
fl4->flowi4_oif = l3mdev_master_ifindex_by_index(net, oif); |
077fbac40 net: xfrm: suppor... |
31 |
fl4->flowi4_mark = mark; |
66cdb3ca2 [IPSEC]: Move flo... |
32 |
if (saddr) |
8f01cb082 ipv4: xfrm: Elimi... |
33 |
fl4->saddr = saddr->a4; |
66cdb3ca2 [IPSEC]: Move flo... |
34 |
|
58189ca7b net: Fix vti use ... |
35 |
fl4->flowi4_flags = FLOWI_FLAG_SKIP_NH_OIF; |
8f01cb082 ipv4: xfrm: Elimi... |
36 |
rt = __ip_route_output_key(net, fl4); |
b23dd4fe4 ipv4: Make output... |
37 38 39 40 |
if (!IS_ERR(rt)) return &rt->dst; return ERR_CAST(rt); |
66cdb3ca2 [IPSEC]: Move flo... |
41 |
} |
42a7b32b7 xfrm: Add oif to ... |
42 |
static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, int oif, |
8f01cb082 ipv4: xfrm: Elimi... |
43 |
const xfrm_address_t *saddr, |
077fbac40 net: xfrm: suppor... |
44 45 |
const xfrm_address_t *daddr, u32 mark) |
8f01cb082 ipv4: xfrm: Elimi... |
46 47 |
{ struct flowi4 fl4; |
077fbac40 net: xfrm: suppor... |
48 |
return __xfrm4_dst_lookup(net, &fl4, tos, oif, saddr, daddr, mark); |
8f01cb082 ipv4: xfrm: Elimi... |
49 |
} |
42a7b32b7 xfrm: Add oif to ... |
50 |
static int xfrm4_get_saddr(struct net *net, int oif, |
077fbac40 net: xfrm: suppor... |
51 52 |
xfrm_address_t *saddr, xfrm_address_t *daddr, u32 mark) |
66cdb3ca2 [IPSEC]: Move flo... |
53 54 |
{ struct dst_entry *dst; |
8f01cb082 ipv4: xfrm: Elimi... |
55 |
struct flowi4 fl4; |
66cdb3ca2 [IPSEC]: Move flo... |
56 |
|
077fbac40 net: xfrm: suppor... |
57 |
dst = __xfrm4_dst_lookup(net, &fl4, 0, oif, NULL, daddr, mark); |
66cdb3ca2 [IPSEC]: Move flo... |
58 59 |
if (IS_ERR(dst)) return -EHOSTUNREACH; |
8f01cb082 ipv4: xfrm: Elimi... |
60 |
saddr->a4 = fl4.saddr; |
66cdb3ca2 [IPSEC]: Move flo... |
61 62 |
dst_release(dst); return 0; |
a1e59abf8 [XFRM]: Fix wildc... |
63 |
} |
87c1e12b5 ipsec: Fix bogus ... |
64 |
static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, |
0c7b3eefb xfrm: Mark flowi ... |
65 |
const struct flowi *fl) |
25ee3286d [IPSEC]: Merge co... |
66 67 |
{ struct rtable *rt = (struct rtable *)xdst->route; |
7e1dc7b6f net: Use flowi4 a... |
68 |
const struct flowi4 *fl4 = &fl->u.ip4; |
1da177e4c Linux-2.6.12-rc2 |
69 |
|
b73233960 ipv4: fix ipsec f... |
70 |
xdst->u.rt.rt_iif = fl4->flowi4_iif; |
1da177e4c Linux-2.6.12-rc2 |
71 |
|
25ee3286d [IPSEC]: Merge co... |
72 73 |
xdst->u.dst.dev = dev; dev_hold(dev); |
433722622 [IPSEC]: IPv4 ove... |
74 |
|
25ee3286d [IPSEC]: Merge co... |
75 76 |
/* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ |
9917e1e87 ipv4: Turn rt->rt... |
77 |
xdst->u.rt.rt_is_input = rt->rt_is_input; |
25ee3286d [IPSEC]: Merge co... |
78 79 80 |
xdst->u.rt.rt_flags = rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST | RTCF_LOCAL); xdst->u.rt.rt_type = rt->rt_type; |
77d5bc7e6 ipv4: Revert remo... |
81 |
xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway; |
1550c1719 ipv4: Prepare rta... |
82 83 84 |
xdst->u.rt.rt_gw_family = rt->rt_gw_family; if (rt->rt_gw_family == AF_INET) xdst->u.rt.rt_gw4 = rt->rt_gw4; |
0f5f7d7bf ipv4: Add support... |
85 86 |
else if (rt->rt_gw_family == AF_INET6) xdst->u.rt.rt_gw6 = rt->rt_gw6; |
5943634fc ipv4: Maintain re... |
87 |
xdst->u.rt.rt_pmtu = rt->rt_pmtu; |
d52e5a7e7 ipv4: lock mtu in... |
88 |
xdst->u.rt.rt_mtu_locked = rt->rt_mtu_locked; |
caacf05e5 ipv4: Properly pu... |
89 |
INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); |
510c321b5 xfrm: reuse uncac... |
90 |
rt_add_uncached_list(&xdst->u.rt); |
1da177e4c Linux-2.6.12-rc2 |
91 |
|
1da177e4c Linux-2.6.12-rc2 |
92 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
93 |
} |
6700c2709 net: Pass optiona... |
94 |
static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk, |
bd085ef67 net: add bool con... |
95 96 |
struct sk_buff *skb, u32 mtu, bool confirm_neigh) |
1da177e4c Linux-2.6.12-rc2 |
97 98 99 |
{ struct xfrm_dst *xdst = (struct xfrm_dst *)dst; struct dst_entry *path = xdst->route; |
bd085ef67 net: add bool con... |
100 |
path->ops->update_pmtu(path, sk, skb, mtu, confirm_neigh); |
1da177e4c Linux-2.6.12-rc2 |
101 |
} |
6700c2709 net: Pass optiona... |
102 103 |
static void xfrm4_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb) |
55be7a9c6 ipv4: Add redirec... |
104 105 106 |
{ struct xfrm_dst *xdst = (struct xfrm_dst *)dst; struct dst_entry *path = xdst->route; |
6700c2709 net: Pass optiona... |
107 |
path->ops->redirect(path, sk, skb); |
55be7a9c6 ipv4: Add redirec... |
108 |
} |
aabc9761b [IPSEC]: Store id... |
109 110 111 |
static void xfrm4_dst_destroy(struct dst_entry *dst) { struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
62fa8a846 net: Implement re... |
112 |
dst_destroy_metrics_generic(dst); |
510c321b5 xfrm: reuse uncac... |
113 114 |
if (xdst->u.rt.rt_uncached_list) rt_del_uncached_list(&xdst->u.rt); |
aabc9761b [IPSEC]: Store id... |
115 116 117 118 119 120 |
xfrm_dst_destroy(xdst); } static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, int unregister) { |
aabc9761b [IPSEC]: Store id... |
121 122 |
if (!unregister) return; |
aabc9761b [IPSEC]: Store id... |
123 124 |
xfrm_dst_ifdown(dst, dev); } |
a8a572a6b xfrm: dst_entries... |
125 |
static struct dst_ops xfrm4_dst_ops_template = { |
1da177e4c Linux-2.6.12-rc2 |
126 |
.family = AF_INET, |
1da177e4c Linux-2.6.12-rc2 |
127 |
.update_pmtu = xfrm4_update_pmtu, |
55be7a9c6 ipv4: Add redirec... |
128 |
.redirect = xfrm4_redirect, |
62fa8a846 net: Implement re... |
129 |
.cow_metrics = dst_cow_metrics_generic, |
aabc9761b [IPSEC]: Store id... |
130 131 |
.destroy = xfrm4_dst_destroy, .ifdown = xfrm4_dst_ifdown, |
862b82c6f [IPSEC]: Merge mo... |
132 |
.local_out = __ip_local_out, |
3c2a89ddc net: xfrm: revert... |
133 |
.gc_thresh = 32768, |
1da177e4c Linux-2.6.12-rc2 |
134 |
}; |
37b103830 xfrm: policy: mak... |
135 |
static const struct xfrm_policy_afinfo xfrm4_policy_afinfo = { |
a8a572a6b xfrm: dst_entries... |
136 |
.dst_ops = &xfrm4_dst_ops_template, |
1da177e4c Linux-2.6.12-rc2 |
137 |
.dst_lookup = xfrm4_dst_lookup, |
a1e59abf8 [XFRM]: Fix wildc... |
138 |
.get_saddr = xfrm4_get_saddr, |
25ee3286d [IPSEC]: Merge co... |
139 |
.fill_dst = xfrm4_fill_dst, |
2774c131b xfrm: Handle blac... |
140 |
.blackhole_route = ipv4_blackhole_route, |
1da177e4c Linux-2.6.12-rc2 |
141 |
}; |
f816700aa xfrm4: fix build ... |
142 |
#ifdef CONFIG_SYSCTL |
a44a4a006 xfrm: export xfrm... |
143 144 |
static struct ctl_table xfrm4_policy_table[] = { { |
a44a4a006 xfrm: export xfrm... |
145 |
.procname = "xfrm4_gc_thresh", |
d7c7544c3 netns xfrm: deal ... |
146 |
.data = &init_net.xfrm.xfrm4_dst_ops.gc_thresh, |
a44a4a006 xfrm: export xfrm... |
147 148 149 150 151 152 |
.maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, }, { } }; |
318d3cc04 net: xfrm: fix ol... |
153 |
static __net_init int xfrm4_net_sysctl_init(struct net *net) |
8d068875c xfrm: make gc_thr... |
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
{ struct ctl_table *table; struct ctl_table_header *hdr; table = xfrm4_policy_table; if (!net_eq(net, &init_net)) { table = kmemdup(table, sizeof(xfrm4_policy_table), GFP_KERNEL); if (!table) goto err_alloc; table[0].data = &net->xfrm.xfrm4_dst_ops.gc_thresh; } hdr = register_net_sysctl(net, "net/ipv4", table); if (!hdr) goto err_reg; net->ipv4.xfrm4_hdr = hdr; return 0; err_reg: if (!net_eq(net, &init_net)) kfree(table); err_alloc: return -ENOMEM; } |
318d3cc04 net: xfrm: fix ol... |
180 |
static __net_exit void xfrm4_net_sysctl_exit(struct net *net) |
8d068875c xfrm: make gc_thr... |
181 182 |
{ struct ctl_table *table; |
51456b291 ipv4: coding styl... |
183 |
if (!net->ipv4.xfrm4_hdr) |
8d068875c xfrm: make gc_thr... |
184 185 186 187 188 189 190 |
return; table = net->ipv4.xfrm4_hdr->ctl_table_arg; unregister_net_sysctl_table(net->ipv4.xfrm4_hdr); if (!net_eq(net, &init_net)) kfree(table); } |
a8a572a6b xfrm: dst_entries... |
191 |
#else /* CONFIG_SYSCTL */ |
318d3cc04 net: xfrm: fix ol... |
192 |
static inline int xfrm4_net_sysctl_init(struct net *net) |
a8a572a6b xfrm: dst_entries... |
193 194 195 |
{ return 0; } |
318d3cc04 net: xfrm: fix ol... |
196 |
static inline void xfrm4_net_sysctl_exit(struct net *net) |
a8a572a6b xfrm: dst_entries... |
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
{ } #endif static int __net_init xfrm4_net_init(struct net *net) { int ret; memcpy(&net->xfrm.xfrm4_dst_ops, &xfrm4_dst_ops_template, sizeof(xfrm4_dst_ops_template)); ret = dst_entries_init(&net->xfrm.xfrm4_dst_ops); if (ret) return ret; ret = xfrm4_net_sysctl_init(net); if (ret) dst_entries_destroy(&net->xfrm.xfrm4_dst_ops); return ret; } static void __net_exit xfrm4_net_exit(struct net *net) { xfrm4_net_sysctl_exit(net); dst_entries_destroy(&net->xfrm.xfrm4_dst_ops); } |
8d068875c xfrm: make gc_thr... |
223 224 225 226 227 |
static struct pernet_operations __net_initdata xfrm4_net_ops = { .init = xfrm4_net_init, .exit = xfrm4_net_exit, }; |
a44a4a006 xfrm: export xfrm... |
228 |
|
1da177e4c Linux-2.6.12-rc2 |
229 230 |
static void __init xfrm4_policy_init(void) { |
a2817d8b2 xfrm: policy: rem... |
231 |
xfrm_policy_register_afinfo(&xfrm4_policy_afinfo, AF_INET); |
1da177e4c Linux-2.6.12-rc2 |
232 |
} |
703fb94ec xfrm: Fix the gc ... |
233 |
void __init xfrm4_init(void) |
1da177e4c Linux-2.6.12-rc2 |
234 |
{ |
d7c7544c3 netns xfrm: deal ... |
235 236 |
xfrm4_state_init(); xfrm4_policy_init(); |
2f32b51b6 xfrm: Introduce x... |
237 |
xfrm4_protocol_init(); |
8d068875c xfrm: make gc_thr... |
238 |
register_pernet_subsys(&xfrm4_net_ops); |
1da177e4c Linux-2.6.12-rc2 |
239 |
} |