221 if (np->opt && np->opt->srcrt) { |
221 if (np->opt && np->opt->srcrt) { |
222 struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; |
222 struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; |
223 ipv6_addr_copy(&fl.fl6_dst, rt0->addr); |
223 ipv6_addr_copy(&fl.fl6_dst, rt0->addr); |
224 } |
224 } |
225 |
225 |
226 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, " |
226 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", |
227 "src:" NIP6_FMT " dst:" NIP6_FMT "\n", |
|
228 __func__, skb, skb->len, |
227 __func__, skb, skb->len, |
229 NIP6(fl.fl6_src), NIP6(fl.fl6_dst)); |
228 &fl.fl6_src, &fl.fl6_dst); |
230 |
229 |
231 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); |
230 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); |
232 |
231 |
233 if (!(transport->param_flags & SPP_PMTUD_ENABLE)) |
232 if (!(transport->param_flags & SPP_PMTUD_ENABLE)) |
234 skb->local_df = 1; |
233 skb->local_df = 1; |
250 ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr); |
249 ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr); |
251 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) |
250 if (ipv6_addr_type(&daddr->v6.sin6_addr) & IPV6_ADDR_LINKLOCAL) |
252 fl.oif = daddr->v6.sin6_scope_id; |
251 fl.oif = daddr->v6.sin6_scope_id; |
253 |
252 |
254 |
253 |
255 SCTP_DEBUG_PRINTK("%s: DST=" NIP6_FMT " ", |
254 SCTP_DEBUG_PRINTK("%s: DST=%pI6 ", __func__, &fl.fl6_dst); |
256 __func__, NIP6(fl.fl6_dst)); |
|
257 |
255 |
258 if (saddr) { |
256 if (saddr) { |
259 ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr); |
257 ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr); |
260 SCTP_DEBUG_PRINTK( |
258 SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl.fl6_src); |
261 "SRC=" NIP6_FMT " - ", |
|
262 NIP6(fl.fl6_src)); |
|
263 } |
259 } |
264 |
260 |
265 dst = ip6_route_output(&init_net, NULL, &fl); |
261 dst = ip6_route_output(&init_net, NULL, &fl); |
266 if (!dst->error) { |
262 if (!dst->error) { |
267 struct rt6_info *rt; |
263 struct rt6_info *rt; |
268 rt = (struct rt6_info *)dst; |
264 rt = (struct rt6_info *)dst; |
269 SCTP_DEBUG_PRINTK( |
265 SCTP_DEBUG_PRINTK("rt6_dst:%pI6 rt6_src:%pI6\n", |
270 "rt6_dst:" NIP6_FMT " rt6_src:" NIP6_FMT "\n", |
266 &rt->rt6i_dst.addr, &rt->rt6i_src.addr); |
271 NIP6(rt->rt6i_dst.addr), NIP6(rt->rt6i_src.addr)); |
|
272 return dst; |
267 return dst; |
273 } |
268 } |
274 SCTP_DEBUG_PRINTK("NO ROUTE\n"); |
269 SCTP_DEBUG_PRINTK("NO ROUTE\n"); |
275 dst_release(dst); |
270 dst_release(dst); |
276 return NULL; |
271 return NULL; |
312 sctp_scope_t scope; |
307 sctp_scope_t scope; |
313 union sctp_addr *baddr = NULL; |
308 union sctp_addr *baddr = NULL; |
314 __u8 matchlen = 0; |
309 __u8 matchlen = 0; |
315 __u8 bmatchlen; |
310 __u8 bmatchlen; |
316 |
311 |
317 SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p " |
312 SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p daddr:%pI6 ", |
318 "daddr:" NIP6_FMT " ", |
313 __func__, asoc, dst, &daddr->v6.sin6_addr); |
319 __func__, asoc, dst, NIP6(daddr->v6.sin6_addr)); |
|
320 |
314 |
321 if (!asoc) { |
315 if (!asoc) { |
322 ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)), |
316 ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)), |
323 dst ? ip6_dst_idev(dst)->dev : NULL, |
317 dst ? ip6_dst_idev(dst)->dev : NULL, |
324 &daddr->v6.sin6_addr, |
318 &daddr->v6.sin6_addr, |
325 inet6_sk(&sk->inet.sk)->srcprefs, |
319 inet6_sk(&sk->inet.sk)->srcprefs, |
326 &saddr->v6.sin6_addr); |
320 &saddr->v6.sin6_addr); |
327 SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: " NIP6_FMT "\n", |
321 SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: %pI6\n", |
328 NIP6(saddr->v6.sin6_addr)); |
322 &saddr->v6.sin6_addr); |
329 return; |
323 return; |
330 } |
324 } |
331 |
325 |
332 scope = sctp_scope(daddr); |
326 scope = sctp_scope(daddr); |
333 |
327 |
351 } |
345 } |
352 } |
346 } |
353 |
347 |
354 if (baddr) { |
348 if (baddr) { |
355 memcpy(saddr, baddr, sizeof(union sctp_addr)); |
349 memcpy(saddr, baddr, sizeof(union sctp_addr)); |
356 SCTP_DEBUG_PRINTK("saddr: " NIP6_FMT "\n", |
350 SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr); |
357 NIP6(saddr->v6.sin6_addr)); |
|
358 } else { |
351 } else { |
359 printk(KERN_ERR "%s: asoc:%p Could not find a valid source " |
352 printk(KERN_ERR "%s: asoc:%p Could not find a valid source " |
360 "address for the dest:" NIP6_FMT "\n", |
353 "address for the dest:%pI6\n", |
361 __func__, asoc, NIP6(daddr->v6.sin6_addr)); |
354 __func__, asoc, &daddr->v6.sin6_addr); |
362 } |
355 } |
363 |
356 |
364 rcu_read_unlock(); |
357 rcu_read_unlock(); |
365 } |
358 } |
366 |
359 |
725 } |
718 } |
726 |
719 |
727 /* Dump the v6 addr to the seq file. */ |
720 /* Dump the v6 addr to the seq file. */ |
728 static void sctp_v6_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr) |
721 static void sctp_v6_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr) |
729 { |
722 { |
730 seq_printf(seq, NIP6_FMT " ", NIP6(addr->v6.sin6_addr)); |
723 seq_printf(seq, "%pI6 ", &addr->v6.sin6_addr); |
731 } |
724 } |
732 |
725 |
733 static void sctp_v6_ecn_capable(struct sock *sk) |
726 static void sctp_v6_ecn_capable(struct sock *sk) |
734 { |
727 { |
735 inet6_sk(sk)->tclass |= INET_ECN_ECT_0; |
728 inet6_sk(sk)->tclass |= INET_ECN_ECT_0; |