Skip to content
This repository has been archived by the owner on Sep 18, 2022. It is now read-only.

Commit

Permalink
Revert: "net: ip, ipv6: handle gso skbs in forwarding path"
Browse files Browse the repository at this point in the history
This reverts commit 29a3cd4 which is
commit fe6cc55 upstream.

Cc: Herbert Xu <[email protected]>
Cc: Marcelo Ricardo Leitner <[email protected]>
Cc: Florian Westphal <[email protected]>
Cc: David S. Miller <[email protected]>
Cc: Thomas Jarosch <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
gregkh committed Aug 7, 2014
1 parent 473d8a2 commit 68199d6
Show file tree
Hide file tree
Showing 3 changed files with 3 additions and 95 deletions.
17 changes: 0 additions & 17 deletions include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -2608,22 +2608,5 @@ static inline bool skb_is_recycleable(const struct sk_buff *skb, int skb_size)

return true;
}

/**
* skb_gso_network_seglen - Return length of individual segments of a gso packet
*
* @skb: GSO skb
*
* skb_gso_network_seglen is used to determine the real size of the
* individual segments, including Layer3 (IP, IPv6) and L4 headers (TCP/UDP).
*
* The MAC/L2 header is not accounted for.
*/
static inline unsigned int skb_gso_network_seglen(const struct sk_buff *skb)
{
unsigned int hdr_len = skb_transport_header(skb) -
skb_network_header(skb);
return hdr_len + skb_gso_transport_seglen(skb);
}
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
68 changes: 2 additions & 66 deletions net/ipv4/ip_forward.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,68 +39,6 @@
#include <net/route.h>
#include <net/xfrm.h>

static bool ip_may_fragment(const struct sk_buff *skb)
{
return unlikely((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0) ||
skb->local_df;
}

static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
{
if (skb->len <= mtu)
return false;

if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
return false;

return true;
}

static bool ip_gso_exceeds_dst_mtu(const struct sk_buff *skb)
{
unsigned int mtu;

if (skb->local_df || !skb_is_gso(skb))
return false;

mtu = dst_mtu(skb_dst(skb));

/* if seglen > mtu, do software segmentation for IP fragmentation on
* output. DF bit cannot be set since ip_forward would have sent
* icmp error.
*/
return skb_gso_network_seglen(skb) > mtu;
}

/* called if GSO skb needs to be fragmented on forward */
static int ip_forward_finish_gso(struct sk_buff *skb)
{
struct sk_buff *segs;
int ret = 0;

segs = skb_gso_segment(skb, 0);
if (IS_ERR(segs)) {
kfree_skb(skb);
return -ENOMEM;
}

consume_skb(skb);

do {
struct sk_buff *nskb = segs->next;
int err;

segs->next = NULL;
err = dst_output(segs);

if (err && ret == 0)
ret = err;
segs = nskb;
} while (segs);

return ret;
}

static int ip_forward_finish(struct sk_buff *skb)
{
struct ip_options * opt = &(IPCB(skb)->opt);
Expand All @@ -110,9 +48,6 @@ static int ip_forward_finish(struct sk_buff *skb)
if (unlikely(opt->optlen))
ip_forward_options(skb);

if (ip_gso_exceeds_dst_mtu(skb))
return ip_forward_finish_gso(skb);

return dst_output(skb);
}

Expand Down Expand Up @@ -152,7 +87,8 @@ int ip_forward(struct sk_buff *skb)
if (opt->is_strictroute && opt->nexthop != rt->rt_gateway)
goto sr_failed;

if (!ip_may_fragment(skb) && ip_exceeds_mtu(skb, dst_mtu(&rt->dst))) {
if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
(ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) {
IP_INC_STATS(dev_net(rt->dst.dev), IPSTATS_MIB_FRAGFAILS);
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
htonl(dst_mtu(&rt->dst)));
Expand Down
13 changes: 1 addition & 12 deletions net/ipv6/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,17 +382,6 @@ static inline int ip6_forward_finish(struct sk_buff *skb)
return dst_output(skb);
}

static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
{
if (skb->len <= mtu || skb->local_df)
return false;

if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
return false;

return true;
}

int ip6_forward(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
Expand Down Expand Up @@ -514,7 +503,7 @@ int ip6_forward(struct sk_buff *skb)
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;

if (ip6_pkt_too_big(skb, mtu)) {
if (skb->len > mtu && !skb_is_gso(skb)) {
/* Again, force OUTPUT device used as source address */
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
Expand Down

0 comments on commit 68199d6

Please sign in to comment.