aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2011-04-26 17:52:27 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-27 16:14:05 -0400
commit9c6a02f41d10dc9fbf5dd42058e8846f38dd2d9a (patch)
treec6ce6904ce9517fbba4b6b9b5c02c0d604b33e59 /net
parent9914ae3ca770389a3bec3114d0a07532a7f235dd (diff)
sctp: make sctp over IPv6 work with IPsec
SCTP never called xfrm_output after it's v6 route lookups so that never really worked with ipsec. Additioanlly, we never passed port nubmers and protocol in the flowi, so any port based policies were never applied as well. Now that we can fixed ipv6 routing lookup code, using ip6_dst_lookup_flow() and pass port numbers. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/sctp/ipv6.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 51c048d256f5..593c80162913 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -262,22 +262,27 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
262 __u8 matchlen = 0; 262 __u8 matchlen = 0;
263 __u8 bmatchlen; 263 __u8 bmatchlen;
264 sctp_scope_t scope; 264 sctp_scope_t scope;
265 int err = 0;
266 265
267 memset(fl6, 0, sizeof(struct flowi6)); 266 memset(fl6, 0, sizeof(struct flowi6));
268 ipv6_addr_copy(&fl6->daddr, &daddr->v6.sin6_addr); 267 ipv6_addr_copy(&fl6->daddr, &daddr->v6.sin6_addr);
268 fl6->fl6_dport = daddr->v6.sin6_port;
269 fl6->flowi6_proto = IPPROTO_SCTP;
269 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) 270 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL)
270 fl6->flowi6_oif = daddr->v6.sin6_scope_id; 271 fl6->flowi6_oif = daddr->v6.sin6_scope_id;
271 272
272 273
273 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr); 274 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl6->daddr);
274 275
276 if (asoc)
277 fl6->fl6_sport = htons(asoc->base.bind_addr.port);
278
275 if (saddr) { 279 if (saddr) {
276 ipv6_addr_copy(&fl6->saddr, &saddr->v6.sin6_addr); 280 ipv6_addr_copy(&fl6->saddr, &saddr->v6.sin6_addr);
281 fl6->fl6_sport = saddr->v6.sin6_port;
277 SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); 282 SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr);
278 } 283 }
279 284
280 err = ip6_dst_lookup(sk, &dst, fl6); 285 dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
281 if (!asoc || saddr) 286 if (!asoc || saddr)
282 goto out; 287 goto out;
283 288
@@ -286,7 +291,7 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
286 /* ip6_dst_lookup has filled in the fl6->saddr for us. Check 291 /* ip6_dst_lookup has filled in the fl6->saddr for us. Check
287 * to see if we can use it. 292 * to see if we can use it.
288 */ 293 */
289 if (!err) { 294 if (!IS_ERR(dst)) {
290 /* Walk through the bind address list and look for a bind 295 /* Walk through the bind address list and look for a bind
291 * address that matches the source address of the returned dst. 296 * address that matches the source address of the returned dst.
292 */ 297 */
@@ -330,11 +335,12 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
330 rcu_read_unlock(); 335 rcu_read_unlock();
331 if (baddr) { 336 if (baddr) {
332 ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr); 337 ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr);
333 err = ip6_dst_lookup(sk, &dst, fl6); 338 fl6->fl6_sport = baddr->v6.sin6_port;
339 dst = ip6_dst_lookup_flow(sk, fl6, NULL, false);
334 } 340 }
335 341
336out: 342out:
337 if (!err) { 343 if (!IS_ERR(dst)) {
338 struct rt6_info *rt; 344 struct rt6_info *rt;
339 rt = (struct rt6_info *)dst; 345 rt = (struct rt6_info *)dst;
340 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", 346 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n",