Commit 1e4ae39d authored by Sridhar Samudrala's avatar Sridhar Samudrala Committed by Christoph Hellwig

[IPV6]: Allow ipv6 fragmentation via ip6_xmit() when ipfragok is set.

parent 000936d4
......@@ -299,7 +299,8 @@ extern int ipv6_rcv(struct sk_buff *skb,
extern int ip6_xmit(struct sock *sk,
struct sk_buff *skb,
struct flowi *fl,
struct ipv6_txoptions *opt);
struct ipv6_txoptions *opt,
int ipfragok);
extern int ip6_nd_hdr(struct sock *sk,
struct sk_buff *skb,
......
......@@ -196,7 +196,7 @@ static inline int ip6_maybe_reroute(struct sk_buff *skb)
*/
int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
struct ipv6_txoptions *opt)
struct ipv6_txoptions *opt, int ipfragok)
{
struct ipv6_pinfo *np = sk ? inet6_sk(sk) : NULL;
struct in6_addr *first_hop = &fl->fl6_dst;
......@@ -258,13 +258,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
ipv6_addr_copy(&hdr->daddr, first_hop);
mtu = dst_pmtu(dst);
if (skb->len <= mtu) {
if ((skb->len <= mtu) || ipfragok) {
IP6_INC_STATS(Ip6OutRequests);
return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
}
if (net_ratelimit())
printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
skb->dev = dst->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
kfree_skb(skb);
return -EMSGSIZE;
......
......@@ -939,7 +939,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
csum_partial((char *)th, skb->len, skb->csum));
ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
err = ip6_xmit(sk, skb, &fl, opt);
err = ip6_xmit(sk, skb, &fl, opt, 0);
if (err == NET_XMIT_CN)
err = 0;
}
......@@ -1057,7 +1057,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
buff->dst = ip6_route_output(NULL, &fl);
if (buff->dst->error == 0) {
ip6_xmit(NULL, buff, &fl, NULL);
ip6_xmit(NULL, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TcpOutSegs);
TCP_INC_STATS_BH(TcpOutRsts);
return;
......@@ -1120,7 +1120,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
buff->dst = ip6_route_output(NULL, &fl);
if (buff->dst->error == 0) {
ip6_xmit(NULL, buff, &fl, NULL);
ip6_xmit(NULL, buff, &fl, NULL, 0);
TCP_INC_STATS_BH(TcpOutSegs);
return;
}
......@@ -1823,7 +1823,7 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
/* Restore final destination back after routing done */
ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
return ip6_xmit(sk, skb, &fl, np->opt);
return ip6_xmit(sk, skb, &fl, np->opt, 0);
}
static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
......
......@@ -176,7 +176,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
SCTP_INC_STATS(SctpOutSCTPPacks);
return ip6_xmit(sk, skb, &fl, np->opt);
return ip6_xmit(sk, skb, &fl, np->opt, ipfragok);
}
/* Returns the dst cache entry for the given source and destination ip
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment