aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_output.c')
-rw-r--r--net/ipv4/ip_output.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 84f26e8e6c6..8c6563361ab 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -122,6 +122,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
122 newskb->pkt_type = PACKET_LOOPBACK; 122 newskb->pkt_type = PACKET_LOOPBACK;
123 newskb->ip_summed = CHECKSUM_UNNECESSARY; 123 newskb->ip_summed = CHECKSUM_UNNECESSARY;
124 WARN_ON(!skb_dst(newskb)); 124 WARN_ON(!skb_dst(newskb));
125 skb_dst_force(newskb);
125 netif_rx_ni(newskb); 126 netif_rx_ni(newskb);
126 return 0; 127 return 0;
127} 128}
@@ -182,6 +183,7 @@ static inline int ip_finish_output2(struct sk_buff *skb)
182 struct rtable *rt = (struct rtable *)dst; 183 struct rtable *rt = (struct rtable *)dst;
183 struct net_device *dev = dst->dev; 184 struct net_device *dev = dst->dev;
184 unsigned int hh_len = LL_RESERVED_SPACE(dev); 185 unsigned int hh_len = LL_RESERVED_SPACE(dev);
186 struct neighbour *neigh;
185 187
186 if (rt->rt_type == RTN_MULTICAST) { 188 if (rt->rt_type == RTN_MULTICAST) {
187 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len); 189 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len);
@@ -203,10 +205,15 @@ static inline int ip_finish_output2(struct sk_buff *skb)
203 skb = skb2; 205 skb = skb2;
204 } 206 }
205 207
206 if (dst->hh) 208 rcu_read_lock();
207 return neigh_hh_output(dst->hh, skb); 209 neigh = dst_get_neighbour(dst);
208 else if (dst->neighbour) 210 if (neigh) {
209 return dst->neighbour->output(skb); 211 int res = neigh_output(neigh, skb);
212
213 rcu_read_unlock();
214 return res;
215 }
216 rcu_read_unlock();
210 217
211 if (net_ratelimit()) 218 if (net_ratelimit())
212 printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); 219 printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");
@@ -489,7 +496,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
489 496
490 if (first_len - hlen > mtu || 497 if (first_len - hlen > mtu ||
491 ((first_len - hlen) & 7) || 498 ((first_len - hlen) & 7) ||
492 (iph->frag_off & htons(IP_MF|IP_OFFSET)) || 499 ip_is_fragment(iph) ||
493 skb_cloned(skb)) 500 skb_cloned(skb))
494 goto slow_path; 501 goto slow_path;
495 502
@@ -734,7 +741,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
734 int getfrag(void *from, char *to, int offset, int len, 741 int getfrag(void *from, char *to, int offset, int len,
735 int odd, struct sk_buff *skb), 742 int odd, struct sk_buff *skb),
736 void *from, int length, int hh_len, int fragheaderlen, 743 void *from, int length, int hh_len, int fragheaderlen,
737 int transhdrlen, int mtu, unsigned int flags) 744 int transhdrlen, int maxfraglen, unsigned int flags)
738{ 745{
739 struct sk_buff *skb; 746 struct sk_buff *skb;
740 int err; 747 int err;
@@ -767,7 +774,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
767 skb->csum = 0; 774 skb->csum = 0;
768 775
769 /* specify the length of each IP datagram fragment */ 776 /* specify the length of each IP datagram fragment */
770 skb_shinfo(skb)->gso_size = mtu - fragheaderlen; 777 skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen;
771 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; 778 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
772 __skb_queue_tail(queue, skb); 779 __skb_queue_tail(queue, skb);
773 } 780 }
@@ -831,7 +838,7 @@ static int __ip_append_data(struct sock *sk,
831 (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { 838 (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) {
832 err = ip_ufo_append_data(sk, queue, getfrag, from, length, 839 err = ip_ufo_append_data(sk, queue, getfrag, from, length,
833 hh_len, fragheaderlen, transhdrlen, 840 hh_len, fragheaderlen, transhdrlen,
834 mtu, flags); 841 maxfraglen, flags);
835 if (err) 842 if (err)
836 goto error; 843 goto error;
837 return 0; 844 return 0;