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, ...@@ -299,7 +299,8 @@ extern int ipv6_rcv(struct sk_buff *skb,
extern int ip6_xmit(struct sock *sk, extern int ip6_xmit(struct sock *sk,
struct sk_buff *skb, struct sk_buff *skb,
struct flowi *fl, struct flowi *fl,
struct ipv6_txoptions *opt); struct ipv6_txoptions *opt,
int ipfragok);
extern int ip6_nd_hdr(struct sock *sk, extern int ip6_nd_hdr(struct sock *sk,
struct sk_buff *skb, struct sk_buff *skb,
......
...@@ -196,7 +196,7 @@ static inline int ip6_maybe_reroute(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, 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 ipv6_pinfo *np = sk ? inet6_sk(sk) : NULL;
struct in6_addr *first_hop = &fl->fl6_dst; 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, ...@@ -258,13 +258,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
ipv6_addr_copy(&hdr->daddr, first_hop); ipv6_addr_copy(&hdr->daddr, first_hop);
mtu = dst_pmtu(dst); mtu = dst_pmtu(dst);
if (skb->len <= mtu) { if ((skb->len <= mtu) || ipfragok) {
IP6_INC_STATS(Ip6OutRequests); IP6_INC_STATS(Ip6OutRequests);
return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute); return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
} }
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); 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); icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
kfree_skb(skb); kfree_skb(skb);
return -EMSGSIZE; return -EMSGSIZE;
......
...@@ -939,7 +939,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct open_request *req, ...@@ -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)); csum_partial((char *)th, skb->len, skb->csum));
ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr); 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) if (err == NET_XMIT_CN)
err = 0; err = 0;
} }
...@@ -1057,7 +1057,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb) ...@@ -1057,7 +1057,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
buff->dst = ip6_route_output(NULL, &fl); buff->dst = ip6_route_output(NULL, &fl);
if (buff->dst->error == 0) { 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(TcpOutSegs);
TCP_INC_STATS_BH(TcpOutRsts); TCP_INC_STATS_BH(TcpOutRsts);
return; return;
...@@ -1120,7 +1120,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ...@@ -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); buff->dst = ip6_route_output(NULL, &fl);
if (buff->dst->error == 0) { 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(TcpOutSegs);
return; return;
} }
...@@ -1823,7 +1823,7 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok) ...@@ -1823,7 +1823,7 @@ static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
/* Restore final destination back after routing done */ /* Restore final destination back after routing done */
ipv6_addr_copy(&fl.fl6_dst, &np->daddr); 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) 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, ...@@ -176,7 +176,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
SCTP_INC_STATS(SctpOutSCTPPacks); 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 /* 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