diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-09-24 04:31:34 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-24 04:31:34 -0400 |
commit | e6aa0f07cb5e81a7cbeaf3be6e2101234c2f0d30 (patch) | |
tree | 77926550ac0c31b1423bcf193a4ed0ecb7fda2c1 /net/ipv6 | |
parent | d4738792fb86600b6cb7220459d9c47e819b3580 (diff) | |
parent | 72d31053f62c4bc464c2783974926969614a8649 (diff) |
Merge commit 'v2.6.27-rc7' into x86/microcode
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 4 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 2 | ||||
-rw-r--r-- | net/ipv6/esp6.c | 4 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 3 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 23 | ||||
-rw-r--r-- | net/ipv6/ip6_fib.c | 1 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 72 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 6 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 2 | ||||
-rw-r--r-- | net/ipv6/proc.c | 1 | ||||
-rw-r--r-- | net/ipv6/raw.c | 6 | ||||
-rw-r--r-- | net/ipv6/route.c | 15 | ||||
-rw-r--r-- | net/ipv6/syncookies.c | 22 | ||||
-rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 42 | ||||
-rw-r--r-- | net/ipv6/udp.c | 6 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_beet.c | 29 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 4 |
18 files changed, 138 insertions, 106 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a7842c54f58a..7b6a584b62dd 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1106,13 +1106,12 @@ out: | |||
1106 | return ret; | 1106 | return ret; |
1107 | } | 1107 | } |
1108 | 1108 | ||
1109 | int ipv6_dev_get_saddr(struct net_device *dst_dev, | 1109 | int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev, |
1110 | const struct in6_addr *daddr, unsigned int prefs, | 1110 | const struct in6_addr *daddr, unsigned int prefs, |
1111 | struct in6_addr *saddr) | 1111 | struct in6_addr *saddr) |
1112 | { | 1112 | { |
1113 | struct ipv6_saddr_score scores[2], | 1113 | struct ipv6_saddr_score scores[2], |
1114 | *score = &scores[0], *hiscore = &scores[1]; | 1114 | *score = &scores[0], *hiscore = &scores[1]; |
1115 | struct net *net = dev_net(dst_dev); | ||
1116 | struct ipv6_saddr_dst dst; | 1115 | struct ipv6_saddr_dst dst; |
1117 | struct net_device *dev; | 1116 | struct net_device *dev; |
1118 | int dst_type; | 1117 | int dst_type; |
@@ -1689,6 +1688,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev, | |||
1689 | .fc_dst_len = plen, | 1688 | .fc_dst_len = plen, |
1690 | .fc_flags = RTF_UP | flags, | 1689 | .fc_flags = RTF_UP | flags, |
1691 | .fc_nlinfo.nl_net = dev_net(dev), | 1690 | .fc_nlinfo.nl_net = dev_net(dev), |
1691 | .fc_protocol = RTPROT_KERNEL, | ||
1692 | }; | 1692 | }; |
1693 | 1693 | ||
1694 | ipv6_addr_copy(&cfg.fc_dst, pfx); | 1694 | ipv6_addr_copy(&cfg.fc_dst, pfx); |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index f7b535dec860..410046a8cc91 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -732,7 +732,7 @@ int datagram_send_ctl(struct net *net, | |||
732 | LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", | 732 | LIMIT_NETDEBUG(KERN_DEBUG "invalid cmsg type: %d\n", |
733 | cmsg->cmsg_type); | 733 | cmsg->cmsg_type); |
734 | err = -EINVAL; | 734 | err = -EINVAL; |
735 | break; | 735 | goto exit_f; |
736 | } | 736 | } |
737 | } | 737 | } |
738 | 738 | ||
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index c6bb4c6d24b3..b181b08fb761 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -521,6 +521,10 @@ static int esp6_init_state(struct xfrm_state *x) | |||
521 | crypto_aead_ivsize(aead); | 521 | crypto_aead_ivsize(aead); |
522 | switch (x->props.mode) { | 522 | switch (x->props.mode) { |
523 | case XFRM_MODE_BEET: | 523 | case XFRM_MODE_BEET: |
524 | if (x->sel.family != AF_INET6) | ||
525 | x->props.header_len += IPV4_BEET_PHMAXLEN + | ||
526 | (sizeof(struct ipv6hdr) - sizeof(struct iphdr)); | ||
527 | break; | ||
524 | case XFRM_MODE_TRANSPORT: | 528 | case XFRM_MODE_TRANSPORT: |
525 | break; | 529 | break; |
526 | case XFRM_MODE_TUNNEL: | 530 | case XFRM_MODE_TUNNEL: |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 8d05527524e3..f5de3f9dc692 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
93 | if (flags & RT6_LOOKUP_F_SRCPREF_COA) | 93 | if (flags & RT6_LOOKUP_F_SRCPREF_COA) |
94 | srcprefs |= IPV6_PREFER_SRC_COA; | 94 | srcprefs |= IPV6_PREFER_SRC_COA; |
95 | 95 | ||
96 | if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, | 96 | if (ipv6_dev_get_saddr(net, |
97 | ip6_dst_idev(&rt->u.dst)->dev, | ||
97 | &flp->fl6_dst, srcprefs, | 98 | &flp->fl6_dst, srcprefs, |
98 | &saddr)) | 99 | &saddr)) |
99 | goto again; | 100 | goto again; |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index abedf95fdf2d..b3157a0cc15d 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -91,19 +91,22 @@ static struct inet6_protocol icmpv6_protocol = { | |||
91 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, | 91 | .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static __inline__ int icmpv6_xmit_lock(struct sock *sk) | 94 | static __inline__ struct sock *icmpv6_xmit_lock(struct net *net) |
95 | { | 95 | { |
96 | struct sock *sk; | ||
97 | |||
96 | local_bh_disable(); | 98 | local_bh_disable(); |
97 | 99 | ||
100 | sk = icmpv6_sk(net); | ||
98 | if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { | 101 | if (unlikely(!spin_trylock(&sk->sk_lock.slock))) { |
99 | /* This can happen if the output path (f.e. SIT or | 102 | /* This can happen if the output path (f.e. SIT or |
100 | * ip6ip6 tunnel) signals dst_link_failure() for an | 103 | * ip6ip6 tunnel) signals dst_link_failure() for an |
101 | * outgoing ICMP6 packet. | 104 | * outgoing ICMP6 packet. |
102 | */ | 105 | */ |
103 | local_bh_enable(); | 106 | local_bh_enable(); |
104 | return 1; | 107 | return NULL; |
105 | } | 108 | } |
106 | return 0; | 109 | return sk; |
107 | } | 110 | } |
108 | 111 | ||
109 | static __inline__ void icmpv6_xmit_unlock(struct sock *sk) | 112 | static __inline__ void icmpv6_xmit_unlock(struct sock *sk) |
@@ -392,11 +395,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
392 | fl.fl_icmp_code = code; | 395 | fl.fl_icmp_code = code; |
393 | security_skb_classify_flow(skb, &fl); | 396 | security_skb_classify_flow(skb, &fl); |
394 | 397 | ||
395 | sk = icmpv6_sk(net); | 398 | sk = icmpv6_xmit_lock(net); |
396 | np = inet6_sk(sk); | 399 | if (sk == NULL) |
397 | |||
398 | if (icmpv6_xmit_lock(sk)) | ||
399 | return; | 400 | return; |
401 | np = inet6_sk(sk); | ||
400 | 402 | ||
401 | if (!icmpv6_xrlim_allow(sk, type, &fl)) | 403 | if (!icmpv6_xrlim_allow(sk, type, &fl)) |
402 | goto out; | 404 | goto out; |
@@ -539,11 +541,10 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
539 | fl.fl_icmp_type = ICMPV6_ECHO_REPLY; | 541 | fl.fl_icmp_type = ICMPV6_ECHO_REPLY; |
540 | security_skb_classify_flow(skb, &fl); | 542 | security_skb_classify_flow(skb, &fl); |
541 | 543 | ||
542 | sk = icmpv6_sk(net); | 544 | sk = icmpv6_xmit_lock(net); |
543 | np = inet6_sk(sk); | 545 | if (sk == NULL) |
544 | |||
545 | if (icmpv6_xmit_lock(sk)) | ||
546 | return; | 546 | return; |
547 | np = inet6_sk(sk); | ||
547 | 548 | ||
548 | if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) | 549 | if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) |
549 | fl.oif = np->mcast_oif; | 550 | fl.oif = np->mcast_oif; |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 52dddc25d3e6..29c7c99e69f7 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -378,6 +378,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) | |||
378 | 378 | ||
379 | arg.skb = skb; | 379 | arg.skb = skb; |
380 | arg.cb = cb; | 380 | arg.cb = cb; |
381 | arg.net = net; | ||
381 | w->args = &arg; | 382 | w->args = &arg; |
382 | 383 | ||
383 | for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { | 384 | for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 6811901e6b1e..3df2c442d90b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -236,6 +236,10 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
236 | skb_reset_network_header(skb); | 236 | skb_reset_network_header(skb); |
237 | hdr = ipv6_hdr(skb); | 237 | hdr = ipv6_hdr(skb); |
238 | 238 | ||
239 | /* Allow local fragmentation. */ | ||
240 | if (ipfragok) | ||
241 | skb->local_df = 1; | ||
242 | |||
239 | /* | 243 | /* |
240 | * Fill in the IPv6 header | 244 | * Fill in the IPv6 header |
241 | */ | 245 | */ |
@@ -265,7 +269,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
265 | skb->mark = sk->sk_mark; | 269 | skb->mark = sk->sk_mark; |
266 | 270 | ||
267 | mtu = dst_mtu(dst); | 271 | mtu = dst_mtu(dst); |
268 | if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) { | 272 | if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { |
269 | IP6_INC_STATS(ip6_dst_idev(skb->dst), | 273 | IP6_INC_STATS(ip6_dst_idev(skb->dst), |
270 | IPSTATS_MIB_OUTREQUESTS); | 274 | IPSTATS_MIB_OUTREQUESTS); |
271 | return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, | 275 | return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, |
@@ -930,7 +934,7 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
930 | goto out_err_release; | 934 | goto out_err_release; |
931 | 935 | ||
932 | if (ipv6_addr_any(&fl->fl6_src)) { | 936 | if (ipv6_addr_any(&fl->fl6_src)) { |
933 | err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev, | 937 | err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev, |
934 | &fl->fl6_dst, | 938 | &fl->fl6_dst, |
935 | sk ? inet6_sk(sk)->srcprefs : 0, | 939 | sk ? inet6_sk(sk)->srcprefs : 0, |
936 | &fl->fl6_src); | 940 | &fl->fl6_src); |
@@ -939,39 +943,39 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
939 | } | 943 | } |
940 | 944 | ||
941 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 945 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
942 | /* | 946 | /* |
943 | * Here if the dst entry we've looked up | 947 | * Here if the dst entry we've looked up |
944 | * has a neighbour entry that is in the INCOMPLETE | 948 | * has a neighbour entry that is in the INCOMPLETE |
945 | * state and the src address from the flow is | 949 | * state and the src address from the flow is |
946 | * marked as OPTIMISTIC, we release the found | 950 | * marked as OPTIMISTIC, we release the found |
947 | * dst entry and replace it instead with the | 951 | * dst entry and replace it instead with the |
948 | * dst entry of the nexthop router | 952 | * dst entry of the nexthop router |
949 | */ | 953 | */ |
950 | if (!((*dst)->neighbour->nud_state & NUD_VALID)) { | 954 | if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) { |
951 | struct inet6_ifaddr *ifp; | 955 | struct inet6_ifaddr *ifp; |
952 | struct flowi fl_gw; | 956 | struct flowi fl_gw; |
953 | int redirect; | 957 | int redirect; |
954 | 958 | ||
955 | ifp = ipv6_get_ifaddr(net, &fl->fl6_src, | 959 | ifp = ipv6_get_ifaddr(net, &fl->fl6_src, |
956 | (*dst)->dev, 1); | 960 | (*dst)->dev, 1); |
957 | 961 | ||
958 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); | 962 | redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); |
959 | if (ifp) | 963 | if (ifp) |
960 | in6_ifa_put(ifp); | 964 | in6_ifa_put(ifp); |
961 | 965 | ||
962 | if (redirect) { | 966 | if (redirect) { |
963 | /* | 967 | /* |
964 | * We need to get the dst entry for the | 968 | * We need to get the dst entry for the |
965 | * default router instead | 969 | * default router instead |
966 | */ | 970 | */ |
967 | dst_release(*dst); | 971 | dst_release(*dst); |
968 | memcpy(&fl_gw, fl, sizeof(struct flowi)); | 972 | memcpy(&fl_gw, fl, sizeof(struct flowi)); |
969 | memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); | 973 | memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); |
970 | *dst = ip6_route_output(net, sk, &fl_gw); | 974 | *dst = ip6_route_output(net, sk, &fl_gw); |
971 | if ((err = (*dst)->error)) | 975 | if ((err = (*dst)->error)) |
972 | goto out_err_release; | 976 | goto out_err_release; |
973 | } | ||
974 | } | 977 | } |
978 | } | ||
975 | #endif | 979 | #endif |
976 | 980 | ||
977 | return 0; | 981 | return 0; |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ea33b26512c2..4e5eac301f91 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -346,6 +346,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
346 | */ | 346 | */ |
347 | if (optlen == 0) | 347 | if (optlen == 0) |
348 | optval = NULL; | 348 | optval = NULL; |
349 | else if (optval == NULL) | ||
350 | goto e_inval; | ||
349 | else if (optlen < sizeof(struct ipv6_opt_hdr) || | 351 | else if (optlen < sizeof(struct ipv6_opt_hdr) || |
350 | optlen & 0x7 || optlen > 8 * 255) | 352 | optlen & 0x7 || optlen > 8 * 255) |
351 | goto e_inval; | 353 | goto e_inval; |
@@ -909,7 +911,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
909 | } else { | 911 | } else { |
910 | if (np->rxopt.bits.rxinfo) { | 912 | if (np->rxopt.bits.rxinfo) { |
911 | struct in6_pktinfo src_info; | 913 | struct in6_pktinfo src_info; |
912 | src_info.ipi6_ifindex = np->mcast_oif; | 914 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if; |
913 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); | 915 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); |
914 | put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); | 916 | put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); |
915 | } | 917 | } |
@@ -919,7 +921,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
919 | } | 921 | } |
920 | if (np->rxopt.bits.rxoinfo) { | 922 | if (np->rxopt.bits.rxoinfo) { |
921 | struct in6_pktinfo src_info; | 923 | struct in6_pktinfo src_info; |
922 | src_info.ipi6_ifindex = np->mcast_oif; | 924 | src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if; |
923 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); | 925 | ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr); |
924 | put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); | 926 | put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info); |
925 | } | 927 | } |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index beb48e3f038a..f1c62ba0f56b 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -549,7 +549,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | |||
549 | override = 0; | 549 | override = 0; |
550 | in6_ifa_put(ifp); | 550 | in6_ifa_put(ifp); |
551 | } else { | 551 | } else { |
552 | if (ipv6_dev_get_saddr(dev, daddr, | 552 | if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr, |
553 | inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs, | 553 | inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs, |
554 | &tmpaddr)) | 554 | &tmpaddr)) |
555 | return; | 555 | return; |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index f82f6074cf85..0179b66864f1 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -286,7 +286,6 @@ proc_net_fail: | |||
286 | 286 | ||
287 | void ipv6_misc_proc_exit(void) | 287 | void ipv6_misc_proc_exit(void) |
288 | { | 288 | { |
289 | proc_net_remove(&init_net, "sockstat6"); | ||
290 | proc_net_remove(&init_net, "dev_snmp6"); | 289 | proc_net_remove(&init_net, "dev_snmp6"); |
291 | proc_net_remove(&init_net, "snmp6"); | 290 | proc_net_remove(&init_net, "snmp6"); |
292 | unregister_pernet_subsys(&ipv6_proc_ops); | 291 | unregister_pernet_subsys(&ipv6_proc_ops); |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 01d47674f7e5..e53e493606c5 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -377,14 +377,14 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) | |||
377 | skb_checksum_complete(skb)) { | 377 | skb_checksum_complete(skb)) { |
378 | atomic_inc(&sk->sk_drops); | 378 | atomic_inc(&sk->sk_drops); |
379 | kfree_skb(skb); | 379 | kfree_skb(skb); |
380 | return 0; | 380 | return NET_RX_DROP; |
381 | } | 381 | } |
382 | 382 | ||
383 | /* Charge it to the socket. */ | 383 | /* Charge it to the socket. */ |
384 | if (sock_queue_rcv_skb(sk,skb)<0) { | 384 | if (sock_queue_rcv_skb(sk,skb)<0) { |
385 | atomic_inc(&sk->sk_drops); | 385 | atomic_inc(&sk->sk_drops); |
386 | kfree_skb(skb); | 386 | kfree_skb(skb); |
387 | return 0; | 387 | return NET_RX_DROP; |
388 | } | 388 | } |
389 | 389 | ||
390 | return 0; | 390 | return 0; |
@@ -429,7 +429,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb) | |||
429 | if (skb_checksum_complete(skb)) { | 429 | if (skb_checksum_complete(skb)) { |
430 | atomic_inc(&sk->sk_drops); | 430 | atomic_inc(&sk->sk_drops); |
431 | kfree_skb(skb); | 431 | kfree_skb(skb); |
432 | return 0; | 432 | return NET_RX_DROP; |
433 | } | 433 | } |
434 | } | 434 | } |
435 | 435 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 86540b24b27c..9af6115f0f50 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1249,7 +1249,7 @@ install_route: | |||
1249 | 1249 | ||
1250 | if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0) | 1250 | if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0) |
1251 | rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; | 1251 | rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; |
1252 | if (!dst_metric(&rt->u.dst, RTAX_MTU)) | 1252 | if (!dst_mtu(&rt->u.dst)) |
1253 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); | 1253 | rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); |
1254 | if (!dst_metric(&rt->u.dst, RTAX_ADVMSS)) | 1254 | if (!dst_metric(&rt->u.dst, RTAX_ADVMSS)) |
1255 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst)); | 1255 | rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst)); |
@@ -2106,7 +2106,8 @@ static inline size_t rt6_nlmsg_size(void) | |||
2106 | + nla_total_size(sizeof(struct rta_cacheinfo)); | 2106 | + nla_total_size(sizeof(struct rta_cacheinfo)); |
2107 | } | 2107 | } |
2108 | 2108 | ||
2109 | static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | 2109 | static int rt6_fill_node(struct net *net, |
2110 | struct sk_buff *skb, struct rt6_info *rt, | ||
2110 | struct in6_addr *dst, struct in6_addr *src, | 2111 | struct in6_addr *dst, struct in6_addr *src, |
2111 | int iif, int type, u32 pid, u32 seq, | 2112 | int iif, int type, u32 pid, u32 seq, |
2112 | int prefix, int nowait, unsigned int flags) | 2113 | int prefix, int nowait, unsigned int flags) |
@@ -2187,8 +2188,9 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, | |||
2187 | #endif | 2188 | #endif |
2188 | NLA_PUT_U32(skb, RTA_IIF, iif); | 2189 | NLA_PUT_U32(skb, RTA_IIF, iif); |
2189 | } else if (dst) { | 2190 | } else if (dst) { |
2191 | struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst); | ||
2190 | struct in6_addr saddr_buf; | 2192 | struct in6_addr saddr_buf; |
2191 | if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, | 2193 | if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL, |
2192 | dst, 0, &saddr_buf) == 0) | 2194 | dst, 0, &saddr_buf) == 0) |
2193 | NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); | 2195 | NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); |
2194 | } | 2196 | } |
@@ -2233,7 +2235,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg) | |||
2233 | } else | 2235 | } else |
2234 | prefix = 0; | 2236 | prefix = 0; |
2235 | 2237 | ||
2236 | return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, | 2238 | return rt6_fill_node(arg->net, |
2239 | arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, | ||
2237 | NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, | 2240 | NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, |
2238 | prefix, 0, NLM_F_MULTI); | 2241 | prefix, 0, NLM_F_MULTI); |
2239 | } | 2242 | } |
@@ -2299,7 +2302,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2299 | rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); | 2302 | rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); |
2300 | skb->dst = &rt->u.dst; | 2303 | skb->dst = &rt->u.dst; |
2301 | 2304 | ||
2302 | err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, | 2305 | err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, |
2303 | RTM_NEWROUTE, NETLINK_CB(in_skb).pid, | 2306 | RTM_NEWROUTE, NETLINK_CB(in_skb).pid, |
2304 | nlh->nlmsg_seq, 0, 0, 0); | 2307 | nlh->nlmsg_seq, 0, 0, 0); |
2305 | if (err < 0) { | 2308 | if (err < 0) { |
@@ -2326,7 +2329,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) | |||
2326 | if (skb == NULL) | 2329 | if (skb == NULL) |
2327 | goto errout; | 2330 | goto errout; |
2328 | 2331 | ||
2329 | err = rt6_fill_node(skb, rt, NULL, NULL, 0, | 2332 | err = rt6_fill_node(net, skb, rt, NULL, NULL, 0, |
2330 | event, info->pid, seq, 0, 0, 0); | 2333 | event, info->pid, seq, 0, 0, 0); |
2331 | if (err < 0) { | 2334 | if (err < 0) { |
2332 | /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ | 2335 | /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index a46badd1082d..ec394cf5a19b 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -199,10 +199,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
199 | ireq6 = inet6_rsk(req); | 199 | ireq6 = inet6_rsk(req); |
200 | treq = tcp_rsk(req); | 200 | treq = tcp_rsk(req); |
201 | 201 | ||
202 | if (security_inet_conn_request(sk, skb, req)) { | 202 | if (security_inet_conn_request(sk, skb, req)) |
203 | reqsk_free(req); | 203 | goto out_free; |
204 | goto out; | ||
205 | } | ||
206 | 204 | ||
207 | req->mss = mss; | 205 | req->mss = mss; |
208 | ireq->rmt_port = th->source; | 206 | ireq->rmt_port = th->source; |
@@ -255,14 +253,13 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
255 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 253 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; |
256 | fl.fl_ip_sport = inet_sk(sk)->sport; | 254 | fl.fl_ip_sport = inet_sk(sk)->sport; |
257 | security_req_classify_flow(req, &fl); | 255 | security_req_classify_flow(req, &fl); |
258 | if (ip6_dst_lookup(sk, &dst, &fl)) { | 256 | if (ip6_dst_lookup(sk, &dst, &fl)) |
259 | reqsk_free(req); | 257 | goto out_free; |
260 | goto out; | 258 | |
261 | } | ||
262 | if (final_p) | 259 | if (final_p) |
263 | ipv6_addr_copy(&fl.fl6_dst, final_p); | 260 | ipv6_addr_copy(&fl.fl6_dst, final_p); |
264 | if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) | 261 | if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0) |
265 | goto out; | 262 | goto out_free; |
266 | } | 263 | } |
267 | 264 | ||
268 | req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); | 265 | req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW); |
@@ -273,7 +270,10 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
273 | ireq->rcv_wscale = rcv_wscale; | 270 | ireq->rcv_wscale = rcv_wscale; |
274 | 271 | ||
275 | ret = get_cookie_sock(sk, skb, req, dst); | 272 | ret = get_cookie_sock(sk, skb, req, dst); |
276 | 273 | out: | |
277 | out: return ret; | 274 | return ret; |
275 | out_free: | ||
276 | reqsk_free(req); | ||
277 | return NULL; | ||
278 | } | 278 | } |
279 | 279 | ||
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index e6dfaeac6be3..587f8f60c489 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
@@ -156,7 +156,7 @@ static struct ctl_table_header *ip6_base; | |||
156 | int ipv6_static_sysctl_register(void) | 156 | int ipv6_static_sysctl_register(void) |
157 | { | 157 | { |
158 | static struct ctl_table empty[1]; | 158 | static struct ctl_table empty[1]; |
159 | ip6_base = register_net_sysctl_rotable(net_ipv6_ctl_path, empty); | 159 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); |
160 | if (ip6_base == NULL) | 160 | if (ip6_base == NULL) |
161 | return -ENOMEM; | 161 | return -ENOMEM; |
162 | return 0; | 162 | return 0; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index cff778b23a7f..b585c850a89a 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -69,7 +69,8 @@ | |||
69 | #include <linux/scatterlist.h> | 69 | #include <linux/scatterlist.h> |
70 | 70 | ||
71 | static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); | 71 | static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb); |
72 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); | 72 | static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, |
73 | struct request_sock *req); | ||
73 | 74 | ||
74 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); | 75 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); |
75 | 76 | ||
@@ -748,7 +749,7 @@ static int tcp_v6_md5_hash_pseudoheader(struct tcp_md5sig_pool *hp, | |||
748 | ipv6_addr_copy(&bp->saddr, saddr); | 749 | ipv6_addr_copy(&bp->saddr, saddr); |
749 | ipv6_addr_copy(&bp->daddr, daddr); | 750 | ipv6_addr_copy(&bp->daddr, daddr); |
750 | bp->protocol = cpu_to_be32(IPPROTO_TCP); | 751 | bp->protocol = cpu_to_be32(IPPROTO_TCP); |
751 | bp->len = cpu_to_be16(nbytes); | 752 | bp->len = cpu_to_be32(nbytes); |
752 | 753 | ||
753 | sg_init_one(&sg, bp, sizeof(*bp)); | 754 | sg_init_one(&sg, bp, sizeof(*bp)); |
754 | return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp)); | 755 | return crypto_hash_update(&hp->md5_desc, &sg, sizeof(*bp)); |
@@ -849,28 +850,17 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) | |||
849 | hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); | 850 | hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); |
850 | hash_location = tcp_parse_md5sig_option(th); | 851 | hash_location = tcp_parse_md5sig_option(th); |
851 | 852 | ||
852 | /* do we have a hash as expected? */ | 853 | /* We've parsed the options - do we have a hash? */ |
853 | if (!hash_expected) { | 854 | if (!hash_expected && !hash_location) |
854 | if (!hash_location) | 855 | return 0; |
855 | return 0; | 856 | |
856 | if (net_ratelimit()) { | 857 | if (hash_expected && !hash_location) { |
857 | printk(KERN_INFO "MD5 Hash NOT expected but found " | 858 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5NOTFOUND); |
858 | "(" NIP6_FMT ", %u)->" | ||
859 | "(" NIP6_FMT ", %u)\n", | ||
860 | NIP6(ip6h->saddr), ntohs(th->source), | ||
861 | NIP6(ip6h->daddr), ntohs(th->dest)); | ||
862 | } | ||
863 | return 1; | 859 | return 1; |
864 | } | 860 | } |
865 | 861 | ||
866 | if (!hash_location) { | 862 | if (!hash_expected && hash_location) { |
867 | if (net_ratelimit()) { | 863 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPMD5UNEXPECTED); |
868 | printk(KERN_INFO "MD5 Hash expected but NOT found " | ||
869 | "(" NIP6_FMT ", %u)->" | ||
870 | "(" NIP6_FMT ", %u)\n", | ||
871 | NIP6(ip6h->saddr), ntohs(th->source), | ||
872 | NIP6(ip6h->daddr), ntohs(th->dest)); | ||
873 | } | ||
874 | return 1; | 864 | return 1; |
875 | } | 865 | } |
876 | 866 | ||
@@ -1105,8 +1095,8 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
1105 | *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | | 1095 | *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | |
1106 | (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); | 1096 | (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG); |
1107 | tcp_v6_md5_hash_hdr((__u8 *)topt, key, | 1097 | tcp_v6_md5_hash_hdr((__u8 *)topt, key, |
1108 | &ipv6_hdr(skb)->daddr, | 1098 | &ipv6_hdr(skb)->saddr, |
1109 | &ipv6_hdr(skb)->saddr, t1); | 1099 | &ipv6_hdr(skb)->daddr, t1); |
1110 | } | 1100 | } |
1111 | #endif | 1101 | #endif |
1112 | 1102 | ||
@@ -1149,10 +1139,11 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) | |||
1149 | inet_twsk_put(tw); | 1139 | inet_twsk_put(tw); |
1150 | } | 1140 | } |
1151 | 1141 | ||
1152 | static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) | 1142 | static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, |
1143 | struct request_sock *req) | ||
1153 | { | 1144 | { |
1154 | tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, | 1145 | tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, |
1155 | tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr)); | 1146 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr)); |
1156 | } | 1147 | } |
1157 | 1148 | ||
1158 | 1149 | ||
@@ -2157,6 +2148,7 @@ static int tcpv6_net_init(struct net *net) | |||
2157 | static void tcpv6_net_exit(struct net *net) | 2148 | static void tcpv6_net_exit(struct net *net) |
2158 | { | 2149 | { |
2159 | inet_ctl_sock_destroy(net->ipv6.tcp_sk); | 2150 | inet_ctl_sock_destroy(net->ipv6.tcp_sk); |
2151 | inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET6); | ||
2160 | } | 2152 | } |
2161 | 2153 | ||
2162 | static struct pernet_operations tcpv6_net_ops = { | 2154 | static struct pernet_operations tcpv6_net_ops = { |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index d1477b350f76..a6aecf76a71b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -379,7 +379,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
379 | uh->source, saddr, dif))) { | 379 | uh->source, saddr, dif))) { |
380 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); | 380 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); |
381 | if (buff) { | 381 | if (buff) { |
382 | bh_lock_sock_nested(sk2); | 382 | bh_lock_sock(sk2); |
383 | if (!sock_owned_by_user(sk2)) | 383 | if (!sock_owned_by_user(sk2)) |
384 | udpv6_queue_rcv_skb(sk2, buff); | 384 | udpv6_queue_rcv_skb(sk2, buff); |
385 | else | 385 | else |
@@ -387,7 +387,7 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
387 | bh_unlock_sock(sk2); | 387 | bh_unlock_sock(sk2); |
388 | } | 388 | } |
389 | } | 389 | } |
390 | bh_lock_sock_nested(sk); | 390 | bh_lock_sock(sk); |
391 | if (!sock_owned_by_user(sk)) | 391 | if (!sock_owned_by_user(sk)) |
392 | udpv6_queue_rcv_skb(sk, skb); | 392 | udpv6_queue_rcv_skb(sk, skb); |
393 | else | 393 | else |
@@ -508,7 +508,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
508 | 508 | ||
509 | /* deliver */ | 509 | /* deliver */ |
510 | 510 | ||
511 | bh_lock_sock_nested(sk); | 511 | bh_lock_sock(sk); |
512 | if (!sock_owned_by_user(sk)) | 512 | if (!sock_owned_by_user(sk)) |
513 | udpv6_queue_rcv_skb(sk, skb); | 513 | udpv6_queue_rcv_skb(sk, skb); |
514 | else | 514 | else |
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c index d6ce400f585f..bbd48b101bae 100644 --- a/net/ipv6/xfrm6_mode_beet.c +++ b/net/ipv6/xfrm6_mode_beet.c | |||
@@ -40,16 +40,39 @@ static void xfrm6_beet_make_header(struct sk_buff *skb) | |||
40 | static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) | 40 | static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) |
41 | { | 41 | { |
42 | struct ipv6hdr *top_iph; | 42 | struct ipv6hdr *top_iph; |
43 | 43 | struct ip_beet_phdr *ph; | |
44 | skb_set_network_header(skb, -x->props.header_len); | 44 | struct iphdr *iphv4; |
45 | int optlen, hdr_len; | ||
46 | |||
47 | iphv4 = ip_hdr(skb); | ||
48 | hdr_len = 0; | ||
49 | optlen = XFRM_MODE_SKB_CB(skb)->optlen; | ||
50 | if (unlikely(optlen)) | ||
51 | hdr_len += IPV4_BEET_PHMAXLEN - (optlen & 4); | ||
52 | |||
53 | skb_set_network_header(skb, -x->props.header_len - hdr_len); | ||
54 | if (x->sel.family != AF_INET6) | ||
55 | skb->network_header += IPV4_BEET_PHMAXLEN; | ||
45 | skb->mac_header = skb->network_header + | 56 | skb->mac_header = skb->network_header + |
46 | offsetof(struct ipv6hdr, nexthdr); | 57 | offsetof(struct ipv6hdr, nexthdr); |
47 | skb->transport_header = skb->network_header + sizeof(*top_iph); | 58 | skb->transport_header = skb->network_header + sizeof(*top_iph); |
48 | __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl); | 59 | ph = (struct ip_beet_phdr *)__skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl-hdr_len); |
49 | 60 | ||
50 | xfrm6_beet_make_header(skb); | 61 | xfrm6_beet_make_header(skb); |
51 | 62 | ||
52 | top_iph = ipv6_hdr(skb); | 63 | top_iph = ipv6_hdr(skb); |
64 | if (unlikely(optlen)) { | ||
65 | |||
66 | BUG_ON(optlen < 0); | ||
67 | |||
68 | ph->padlen = 4 - (optlen & 4); | ||
69 | ph->hdrlen = optlen / 8; | ||
70 | ph->nexthdr = top_iph->nexthdr; | ||
71 | if (ph->padlen) | ||
72 | memset(ph + 1, IPOPT_NOP, ph->padlen); | ||
73 | |||
74 | top_iph->nexthdr = IPPROTO_BEETPH; | ||
75 | } | ||
53 | 76 | ||
54 | ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); | 77 | ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); |
55 | ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); | 78 | ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 8f1e0543b3c4..08e4cbbe3f04 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -52,12 +52,14 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, | |||
52 | static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) | 52 | static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) |
53 | { | 53 | { |
54 | struct dst_entry *dst; | 54 | struct dst_entry *dst; |
55 | struct net_device *dev; | ||
55 | 56 | ||
56 | dst = xfrm6_dst_lookup(0, NULL, daddr); | 57 | dst = xfrm6_dst_lookup(0, NULL, daddr); |
57 | if (IS_ERR(dst)) | 58 | if (IS_ERR(dst)) |
58 | return -EHOSTUNREACH; | 59 | return -EHOSTUNREACH; |
59 | 60 | ||
60 | ipv6_dev_get_saddr(ip6_dst_idev(dst)->dev, | 61 | dev = ip6_dst_idev(dst)->dev; |
62 | ipv6_dev_get_saddr(dev_net(dev), dev, | ||
61 | (struct in6_addr *)&daddr->a6, 0, | 63 | (struct in6_addr *)&daddr->a6, 0, |
62 | (struct in6_addr *)&saddr->a6); | 64 | (struct in6_addr *)&saddr->a6); |
63 | dst_release(dst); | 65 | dst_release(dst); |