@@ -60,46 +60,29 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
60
60
{
61
61
struct dst_entry * dst = skb_dst (skb );
62
62
struct net_device * dev = dst -> dev ;
63
+ struct inet6_dev * idev = ip6_dst_idev (dst );
63
64
unsigned int hh_len = LL_RESERVED_SPACE (dev );
64
- int delta = hh_len - skb_headroom ( skb ) ;
65
- const struct in6_addr * nexthop ;
65
+ const struct in6_addr * daddr , * nexthop ;
66
+ struct ipv6hdr * hdr ;
66
67
struct neighbour * neigh ;
67
68
int ret ;
68
69
69
70
/* Be paranoid, rather than too clever. */
70
- if (unlikely (delta > 0 ) && dev -> header_ops ) {
71
- /* pskb_expand_head() might crash, if skb is shared */
72
- if (skb_shared (skb )) {
73
- struct sk_buff * nskb = skb_clone (skb , GFP_ATOMIC );
74
-
75
- if (likely (nskb )) {
76
- if (skb -> sk )
77
- skb_set_owner_w (nskb , skb -> sk );
78
- consume_skb (skb );
79
- } else {
80
- kfree_skb (skb );
81
- }
82
- skb = nskb ;
83
- }
84
- if (skb &&
85
- pskb_expand_head (skb , SKB_DATA_ALIGN (delta ), 0 , GFP_ATOMIC )) {
86
- kfree_skb (skb );
87
- skb = NULL ;
88
- }
71
+ if (unlikely (hh_len > skb_headroom (skb )) && dev -> header_ops ) {
72
+ skb = skb_expand_head (skb , hh_len );
89
73
if (!skb ) {
90
- IP6_INC_STATS (net , ip6_dst_idev ( dst ) , IPSTATS_MIB_OUTDISCARDS );
74
+ IP6_INC_STATS (net , idev , IPSTATS_MIB_OUTDISCARDS );
91
75
return - ENOMEM ;
92
76
}
93
77
}
94
78
95
- if ( ipv6_addr_is_multicast ( & ipv6_hdr (skb )-> daddr )) {
96
- struct inet6_dev * idev = ip6_dst_idev ( skb_dst ( skb )) ;
97
-
79
+ hdr = ipv6_hdr (skb );
80
+ daddr = & hdr -> daddr ;
81
+ if ( ipv6_addr_is_multicast ( daddr )) {
98
82
if (!(dev -> flags & IFF_LOOPBACK ) && sk_mc_loop (sk ) &&
99
83
((mroute6_is_socket (net , skb ) &&
100
84
!(IP6CB (skb )-> flags & IP6SKB_FORWARDED )) ||
101
- ipv6_chk_mcast_addr (dev , & ipv6_hdr (skb )-> daddr ,
102
- & ipv6_hdr (skb )-> saddr ))) {
85
+ ipv6_chk_mcast_addr (dev , daddr , & hdr -> saddr ))) {
103
86
struct sk_buff * newskb = skb_clone (skb , GFP_ATOMIC );
104
87
105
88
/* Do not check for IFF_ALLMULTI; multicast routing
@@ -110,7 +93,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
110
93
net , sk , newskb , NULL , newskb -> dev ,
111
94
dev_loopback_xmit );
112
95
113
- if (ipv6_hdr ( skb ) -> hop_limit == 0 ) {
96
+ if (hdr -> hop_limit == 0 ) {
114
97
IP6_INC_STATS (net , idev ,
115
98
IPSTATS_MIB_OUTDISCARDS );
116
99
kfree_skb (skb );
@@ -119,9 +102,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
119
102
}
120
103
121
104
IP6_UPD_PO_STATS (net , idev , IPSTATS_MIB_OUTMCAST , skb -> len );
122
-
123
- if (IPV6_ADDR_MC_SCOPE (& ipv6_hdr (skb )-> daddr ) <=
124
- IPV6_ADDR_SCOPE_NODELOCAL &&
105
+ if (IPV6_ADDR_MC_SCOPE (daddr ) <= IPV6_ADDR_SCOPE_NODELOCAL &&
125
106
!(dev -> flags & IFF_LOOPBACK )) {
126
107
kfree_skb (skb );
127
108
return 0 ;
@@ -136,10 +117,10 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
136
117
}
137
118
138
119
rcu_read_lock_bh ();
139
- nexthop = rt6_nexthop ((struct rt6_info * )dst , & ipv6_hdr ( skb ) -> daddr );
140
- neigh = __ipv6_neigh_lookup_noref (dst -> dev , nexthop );
120
+ nexthop = rt6_nexthop ((struct rt6_info * )dst , daddr );
121
+ neigh = __ipv6_neigh_lookup_noref (dev , nexthop );
141
122
if (unlikely (!neigh ))
142
- neigh = __neigh_create (& nd_tbl , nexthop , dst -> dev , false);
123
+ neigh = __neigh_create (& nd_tbl , nexthop , dev , false);
143
124
if (!IS_ERR (neigh )) {
144
125
sock_confirm_neigh (skb , neigh );
145
126
ret = neigh_output (neigh , skb , false);
@@ -148,7 +129,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
148
129
}
149
130
rcu_read_unlock_bh ();
150
131
151
- IP6_INC_STATS (net , ip6_dst_idev ( dst ) , IPSTATS_MIB_OUTNOROUTES );
132
+ IP6_INC_STATS (net , idev , IPSTATS_MIB_OUTNOROUTES );
152
133
kfree_skb (skb );
153
134
return - EINVAL ;
154
135
}
0 commit comments