X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=net%2Fipv4%2Fip_output.c;h=d096332f6c6d9e10753531364299f68672f604a7;hb=c3c70c443c2ef1fce31f201a93780c884b903993;hp=f9194f7e39d375a5ca64b42f24c19dfe1973f9b7;hpb=44bb93633f57a55979f3c2589b10fd6a2bfc7c08;p=powerpc.git diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index f9194f7e39..d096332f6c 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -22,7 +22,7 @@ * Fixes: * Alan Cox : Missing nonblock feature in ip_build_xmit. * Mike Kilburn : htons() missing in ip_build_xmit. - * Bradford Johnson: Fix faulty handling of some frames when + * Bradford Johnson: Fix faulty handling of some frames when * no route is found. * Alexander Demenshin: Missing sk/skb free in ip_queue_xmit * (in case if packet not accepted by @@ -33,9 +33,9 @@ * some redundant tests. * Vitaly E. Lavrov : Transparent proxy revived after year coma. * Andi Kleen : Replace ip_reply with ip_send_reply. - * Andi Kleen : Split fast and slow ip_build_xmit path - * for decreased register pressure on x86 - * and more readibility. + * Andi Kleen : Split fast and slow ip_build_xmit path + * for decreased register pressure on x86 + * and more readibility. * Marc Boucher : When call_out_firewall returns FW_QUEUE, * silently drop skb instead of failing with -EPERM. * Detlev Wengorz : Copy protocol for fragments. @@ -49,10 +49,10 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -113,7 +113,7 @@ static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) return ttl; } -/* +/* * Add an ip header to a skbuff and send it out. * */ @@ -163,7 +163,6 @@ EXPORT_SYMBOL_GPL(ip_build_and_send_pkt); static inline int ip_finish_output2(struct sk_buff *skb) { struct dst_entry *dst = skb->dst; - struct hh_cache *hh = dst->hh; struct net_device *dev = dst->dev; int hh_len = LL_RESERVED_SPACE(dev); @@ -182,16 +181,9 @@ static inline int ip_finish_output2(struct sk_buff *skb) skb = skb2; } - if (hh) { - int hh_alen; - - read_lock_bh(&hh->hh_lock); - hh_alen = HH_DATA_ALIGN(hh->hh_len); - memcpy(skb->data - hh_alen, hh->hh_data, hh_alen); - read_unlock_bh(&hh->hh_lock); - skb_push(skb, hh->hh_len); - return hh->hh_output(skb); - } else if (dst->neighbour) + if (dst->hh) + return neigh_hh_output(dst->hh, skb); + else if (dst->neighbour) return dst->neighbour->output(skb); if (net_ratelimit()) @@ -250,7 +242,7 @@ int ip_mc_output(struct sk_buff *skb) struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); if (newskb) NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL, - newskb->dev, + newskb->dev, ip_dev_loopback_xmit); } @@ -284,12 +276,13 @@ int ip_output(struct sk_buff *skb) skb->protocol = htons(ETH_P_IP); return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, - ip_finish_output, + ip_finish_output, !(IPCB(skb)->flags & IPSKB_REROUTED)); } -int ip_queue_xmit(struct sk_buff *skb, struct sock *sk, int ipfragok) +int ip_queue_xmit(struct sk_buff *skb, int ipfragok) { + struct sock *sk = skb->sk; struct inet_sock *inet = inet_sk(sk); struct ip_options *opt = inet->opt; struct rtable *rt; @@ -666,7 +659,7 @@ slow_path: return err; fail: - kfree_skb(skb); + kfree_skb(skb); IP_INC_STATS(IPSTATS_MIB_FRAGFAILS); return err; } @@ -761,7 +754,7 @@ static inline int ip_ufo_append_data(struct sock *sk, * from many pieces of data. Each pieces will be holded on the socket * until ip_push_pending_frames() is called. Each piece can be a page * or non-page data. - * + * * Not only UDP, other transport protocols - e.g. raw sockets - can use * this interface potentially. * @@ -894,7 +887,7 @@ alloc_new_skb: datalen = maxfraglen - fragheaderlen; fraglen = datalen + fragheaderlen; - if ((flags & MSG_MORE) && + if ((flags & MSG_MORE) && !(rt->u.dst.dev->features&NETIF_F_SG)) alloclen = mtu; else @@ -909,14 +902,14 @@ alloc_new_skb: alloclen += rt->u.dst.trailer_len; if (transhdrlen) { - skb = sock_alloc_send_skb(sk, + skb = sock_alloc_send_skb(sk, alloclen + hh_len + 15, (flags & MSG_DONTWAIT), &err); } else { skb = NULL; if (atomic_read(&sk->sk_wmem_alloc) <= 2 * sk->sk_sndbuf) - skb = sock_wmalloc(sk, + skb = sock_wmalloc(sk, alloclen + hh_len + 15, 1, sk->sk_allocation); if (unlikely(skb == NULL)) @@ -977,7 +970,7 @@ alloc_new_skb: unsigned int off; off = skb->len; - if (getfrag(from, skb_put(skb, copy), + if (getfrag(from, skb_put(skb, copy), offset, copy, off, skb) < 0) { __skb_trim(skb, off); err = -EFAULT; @@ -999,7 +992,7 @@ alloc_new_skb: goto error; } get_page(page); - skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); frag = &skb_shinfo(skb)->frags[i]; } } else if (i < MAX_SKB_FRAGS) { @@ -1039,7 +1032,7 @@ alloc_new_skb: error: inet->cork.length -= length; IP_INC_STATS(IPSTATS_MIB_OUTDISCARDS); - return err; + return err; } ssize_t ip_append_page(struct sock *sk, struct page *page, @@ -1263,7 +1256,7 @@ int ip_push_pending_frames(struct sock *sk) skb->dst = dst_clone(&rt->u.dst); /* Netfilter gets whole the not fragmented skb. */ - err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); if (err) { if (err > 0) @@ -1311,21 +1304,21 @@ void ip_flush_pending_frames(struct sock *sk) /* * Fetch data from kernel space and fill in checksum if needed. */ -static int ip_reply_glue_bits(void *dptr, char *to, int offset, +static int ip_reply_glue_bits(void *dptr, char *to, int offset, int len, int odd, struct sk_buff *skb) { - unsigned int csum; + __wsum csum; csum = csum_partial_copy_nocheck(dptr+offset, to, len, 0); skb->csum = csum_block_add(skb->csum, csum, odd); - return 0; + return 0; } -/* +/* * Generic function to send a packet as reply to another packet. * Used to send TCP resets so far. ICMP should use this function too. * - * Should run single threaded per socket because it uses the sock + * Should run single threaded per socket because it uses the sock * structure to pass arguments. * * LATER: switch from ip_build_xmit to ip_append_* @@ -1363,7 +1356,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar /* Not quite clean, but right. */ .uli_u = { .ports = { .sport = skb->h.th->dest, - .dport = skb->h.th->source } }, + .dport = skb->h.th->source } }, .proto = sk->sk_protocol }; security_skb_classify_flow(skb, &fl); if (ip_route_output_key(&rt, &fl))