diff options
Diffstat (limited to 'net/ipv4/xfrm4_policy.c')
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index b057d40adde..13e0e7f659f 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -19,25 +19,23 @@ | |||
19 | static struct xfrm_policy_afinfo xfrm4_policy_afinfo; | 19 | static struct xfrm_policy_afinfo xfrm4_policy_afinfo; |
20 | 20 | ||
21 | static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, | 21 | static struct dst_entry *xfrm4_dst_lookup(struct net *net, int tos, |
22 | xfrm_address_t *saddr, | 22 | const xfrm_address_t *saddr, |
23 | xfrm_address_t *daddr) | 23 | const xfrm_address_t *daddr) |
24 | { | 24 | { |
25 | struct flowi fl = { | 25 | struct flowi4 fl4 = { |
26 | .fl4_dst = daddr->a4, | 26 | .daddr = daddr->a4, |
27 | .fl4_tos = tos, | 27 | .flowi4_tos = tos, |
28 | }; | 28 | }; |
29 | struct dst_entry *dst; | ||
30 | struct rtable *rt; | 29 | struct rtable *rt; |
31 | int err; | ||
32 | 30 | ||
33 | if (saddr) | 31 | if (saddr) |
34 | fl.fl4_src = saddr->a4; | 32 | fl4.saddr = saddr->a4; |
33 | |||
34 | rt = __ip_route_output_key(net, &fl4); | ||
35 | if (!IS_ERR(rt)) | ||
36 | return &rt->dst; | ||
35 | 37 | ||
36 | err = __ip_route_output_key(net, &rt, &fl); | 38 | return ERR_CAST(rt); |
37 | dst = &rt->dst; | ||
38 | if (err) | ||
39 | dst = ERR_PTR(err); | ||
40 | return dst; | ||
41 | } | 39 | } |
42 | 40 | ||
43 | static int xfrm4_get_saddr(struct net *net, | 41 | static int xfrm4_get_saddr(struct net *net, |
@@ -56,9 +54,9 @@ static int xfrm4_get_saddr(struct net *net, | |||
56 | return 0; | 54 | return 0; |
57 | } | 55 | } |
58 | 56 | ||
59 | static int xfrm4_get_tos(struct flowi *fl) | 57 | static int xfrm4_get_tos(const struct flowi *fl) |
60 | { | 58 | { |
61 | return IPTOS_RT_MASK & fl->fl4_tos; /* Strip ECN bits */ | 59 | return IPTOS_RT_MASK & fl->u.ip4.flowi4_tos; /* Strip ECN bits */ |
62 | } | 60 | } |
63 | 61 | ||
64 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, | 62 | static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, |
@@ -68,11 +66,17 @@ static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, | |||
68 | } | 66 | } |
69 | 67 | ||
70 | static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | 68 | static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, |
71 | struct flowi *fl) | 69 | const struct flowi *fl) |
72 | { | 70 | { |
73 | struct rtable *rt = (struct rtable *)xdst->route; | 71 | struct rtable *rt = (struct rtable *)xdst->route; |
72 | const struct flowi4 *fl4 = &fl->u.ip4; | ||
74 | 73 | ||
75 | xdst->u.rt.fl = *fl; | 74 | rt->rt_key_dst = fl4->daddr; |
75 | rt->rt_key_src = fl4->saddr; | ||
76 | rt->rt_tos = fl4->flowi4_tos; | ||
77 | rt->rt_iif = fl4->flowi4_iif; | ||
78 | rt->rt_oif = fl4->flowi4_oif; | ||
79 | rt->rt_mark = fl4->flowi4_mark; | ||
76 | 80 | ||
77 | xdst->u.dst.dev = dev; | 81 | xdst->u.dst.dev = dev; |
78 | dev_hold(dev); | 82 | dev_hold(dev); |
@@ -99,9 +103,10 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
99 | { | 103 | { |
100 | struct iphdr *iph = ip_hdr(skb); | 104 | struct iphdr *iph = ip_hdr(skb); |
101 | u8 *xprth = skb_network_header(skb) + iph->ihl * 4; | 105 | u8 *xprth = skb_network_header(skb) + iph->ihl * 4; |
106 | struct flowi4 *fl4 = &fl->u.ip4; | ||
102 | 107 | ||
103 | memset(fl, 0, sizeof(struct flowi)); | 108 | memset(fl4, 0, sizeof(struct flowi4)); |
104 | fl->mark = skb->mark; | 109 | fl4->flowi4_mark = skb->mark; |
105 | 110 | ||
106 | if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) { | 111 | if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) { |
107 | switch (iph->protocol) { | 112 | switch (iph->protocol) { |
@@ -114,8 +119,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
114 | pskb_may_pull(skb, xprth + 4 - skb->data)) { | 119 | pskb_may_pull(skb, xprth + 4 - skb->data)) { |
115 | __be16 *ports = (__be16 *)xprth; | 120 | __be16 *ports = (__be16 *)xprth; |
116 | 121 | ||
117 | fl->fl_ip_sport = ports[!!reverse]; | 122 | fl4->fl4_sport = ports[!!reverse]; |
118 | fl->fl_ip_dport = ports[!reverse]; | 123 | fl4->fl4_dport = ports[!reverse]; |
119 | } | 124 | } |
120 | break; | 125 | break; |
121 | 126 | ||
@@ -123,8 +128,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
123 | if (pskb_may_pull(skb, xprth + 2 - skb->data)) { | 128 | if (pskb_may_pull(skb, xprth + 2 - skb->data)) { |
124 | u8 *icmp = xprth; | 129 | u8 *icmp = xprth; |
125 | 130 | ||
126 | fl->fl_icmp_type = icmp[0]; | 131 | fl4->fl4_icmp_type = icmp[0]; |
127 | fl->fl_icmp_code = icmp[1]; | 132 | fl4->fl4_icmp_code = icmp[1]; |
128 | } | 133 | } |
129 | break; | 134 | break; |
130 | 135 | ||
@@ -132,7 +137,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
132 | if (pskb_may_pull(skb, xprth + 4 - skb->data)) { | 137 | if (pskb_may_pull(skb, xprth + 4 - skb->data)) { |
133 | __be32 *ehdr = (__be32 *)xprth; | 138 | __be32 *ehdr = (__be32 *)xprth; |
134 | 139 | ||
135 | fl->fl_ipsec_spi = ehdr[0]; | 140 | fl4->fl4_ipsec_spi = ehdr[0]; |
136 | } | 141 | } |
137 | break; | 142 | break; |
138 | 143 | ||
@@ -140,7 +145,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
140 | if (pskb_may_pull(skb, xprth + 8 - skb->data)) { | 145 | if (pskb_may_pull(skb, xprth + 8 - skb->data)) { |
141 | __be32 *ah_hdr = (__be32*)xprth; | 146 | __be32 *ah_hdr = (__be32*)xprth; |
142 | 147 | ||
143 | fl->fl_ipsec_spi = ah_hdr[1]; | 148 | fl4->fl4_ipsec_spi = ah_hdr[1]; |
144 | } | 149 | } |
145 | break; | 150 | break; |
146 | 151 | ||
@@ -148,7 +153,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
148 | if (pskb_may_pull(skb, xprth + 4 - skb->data)) { | 153 | if (pskb_may_pull(skb, xprth + 4 - skb->data)) { |
149 | __be16 *ipcomp_hdr = (__be16 *)xprth; | 154 | __be16 *ipcomp_hdr = (__be16 *)xprth; |
150 | 155 | ||
151 | fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); | 156 | fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); |
152 | } | 157 | } |
153 | break; | 158 | break; |
154 | 159 | ||
@@ -160,20 +165,20 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
160 | if (greflags[0] & GRE_KEY) { | 165 | if (greflags[0] & GRE_KEY) { |
161 | if (greflags[0] & GRE_CSUM) | 166 | if (greflags[0] & GRE_CSUM) |
162 | gre_hdr++; | 167 | gre_hdr++; |
163 | fl->fl_gre_key = gre_hdr[1]; | 168 | fl4->fl4_gre_key = gre_hdr[1]; |
164 | } | 169 | } |
165 | } | 170 | } |
166 | break; | 171 | break; |
167 | 172 | ||
168 | default: | 173 | default: |
169 | fl->fl_ipsec_spi = 0; | 174 | fl4->fl4_ipsec_spi = 0; |
170 | break; | 175 | break; |
171 | } | 176 | } |
172 | } | 177 | } |
173 | fl->proto = iph->protocol; | 178 | fl4->flowi4_proto = iph->protocol; |
174 | fl->fl4_dst = reverse ? iph->saddr : iph->daddr; | 179 | fl4->daddr = reverse ? iph->saddr : iph->daddr; |
175 | fl->fl4_src = reverse ? iph->daddr : iph->saddr; | 180 | fl4->saddr = reverse ? iph->daddr : iph->saddr; |
176 | fl->fl4_tos = iph->tos; | 181 | fl4->flowi4_tos = iph->tos; |
177 | } | 182 | } |
178 | 183 | ||
179 | static inline int xfrm4_garbage_collect(struct dst_ops *ops) | 184 | static inline int xfrm4_garbage_collect(struct dst_ops *ops) |
@@ -196,8 +201,11 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) | |||
196 | { | 201 | { |
197 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | 202 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; |
198 | 203 | ||
204 | dst_destroy_metrics_generic(dst); | ||
205 | |||
199 | if (likely(xdst->u.rt.peer)) | 206 | if (likely(xdst->u.rt.peer)) |
200 | inet_putpeer(xdst->u.rt.peer); | 207 | inet_putpeer(xdst->u.rt.peer); |
208 | |||
201 | xfrm_dst_destroy(xdst); | 209 | xfrm_dst_destroy(xdst); |
202 | } | 210 | } |
203 | 211 | ||
@@ -215,6 +223,7 @@ static struct dst_ops xfrm4_dst_ops = { | |||
215 | .protocol = cpu_to_be16(ETH_P_IP), | 223 | .protocol = cpu_to_be16(ETH_P_IP), |
216 | .gc = xfrm4_garbage_collect, | 224 | .gc = xfrm4_garbage_collect, |
217 | .update_pmtu = xfrm4_update_pmtu, | 225 | .update_pmtu = xfrm4_update_pmtu, |
226 | .cow_metrics = dst_cow_metrics_generic, | ||
218 | .destroy = xfrm4_dst_destroy, | 227 | .destroy = xfrm4_dst_destroy, |
219 | .ifdown = xfrm4_dst_ifdown, | 228 | .ifdown = xfrm4_dst_ifdown, |
220 | .local_out = __ip_local_out, | 229 | .local_out = __ip_local_out, |
@@ -230,6 +239,7 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { | |||
230 | .get_tos = xfrm4_get_tos, | 239 | .get_tos = xfrm4_get_tos, |
231 | .init_path = xfrm4_init_path, | 240 | .init_path = xfrm4_init_path, |
232 | .fill_dst = xfrm4_fill_dst, | 241 | .fill_dst = xfrm4_fill_dst, |
242 | .blackhole_route = ipv4_blackhole_route, | ||
233 | }; | 243 | }; |
234 | 244 | ||
235 | #ifdef CONFIG_SYSCTL | 245 | #ifdef CONFIG_SYSCTL |