sctp: Drop ipfargok in sctp_xmit function
authorHerbert Xu <herbert@gondor.apana.org.au>
Mon, 4 Aug 2008 04:15:08 +0000 (21:15 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 4 Aug 2008 04:15:08 +0000 (21:15 -0700)
The ipfragok flag controls whether the packet may be fragmented
either on the local host on beyond.  The latter is only valid on
IPv4.

In fact, we never want to do the latter even on IPv4 when PMTU is
enabled.  This is because even though we can't fragment packets
within SCTP due to the prtocol's inherent faults, we can still
fragment it at IP layer.  By setting the DF bit we will improve
the PMTU process.

RFC 2960 only says that we SHOULD clear the DF bit in this case,
so we're compliant even if we set the DF bit.  In fact RFC 4960
no longer has this statement.

Once we make this change, we only need to control the local
fragmentation.  There is already a bit in the skb which controls
that, local_df.  So this patch sets that instead of using the
ipfragok argument.

The only complication is that there isn't a struct sock object
per transport, so for IPv4 we have to resort to changing the
pmtudisc field for every packet.  This should be safe though
as the protocol is single-threaded.

Note that after this patch we can remove ipfragok from the rest
of the stack too.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sctp/structs.h
net/sctp/ipv6.c
net/sctp/output.c
net/sctp/protocol.c

index 535a18f57a134fe9ada157e6a053761cba9d6ccb..ab1c472ea75375a45dead4368cabd96b30941b2e 100644 (file)
@@ -524,8 +524,7 @@ static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id,
  */
 struct sctp_af {
        int             (*sctp_xmit)    (struct sk_buff *skb,
-                                        struct sctp_transport *,
-                                        int ipfragok);
+                                        struct sctp_transport *);
        int             (*setsockopt)   (struct sock *sk,
                                         int level,
                                         int optname,
index a238d6834b33ad1ba2728ebbd026016c3b88fc57..483a01d0740a888efb4325358ee33d441f5fe80b 100644 (file)
@@ -195,8 +195,7 @@ out:
 }
 
 /* Based on tcp_v6_xmit() in tcp_ipv6.c. */
-static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
-                       int ipfragok)
+static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
 {
        struct sock *sk = skb->sk;
        struct ipv6_pinfo *np = inet6_sk(sk);
@@ -231,7 +230,10 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
 
        SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
 
-       return ip6_xmit(sk, skb, &fl, np->opt, ipfragok);
+       if (!(transport->param_flags & SPP_PMTUD_ENABLE))
+               skb->local_df = 1;
+
+       return ip6_xmit(sk, skb, &fl, np->opt, 0);
 }
 
 /* Returns the dst cache entry for the given source and destination ip
index 45684646b1dba32a9e1c565713adc527c84095c3..0dc4a7dfb23443eacbe4accda160787443646906 100644 (file)
@@ -586,10 +586,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
                          nskb->len);
 
-       if (tp->param_flags & SPP_PMTUD_ENABLE)
-               (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
-       else
-               (*tp->af_specific->sctp_xmit)(nskb, tp, 1);
+       nskb->local_df = packet->ipfragok;
+       (*tp->af_specific->sctp_xmit)(nskb, tp);
 
 out:
        packet->size = packet->overhead;
index a6e0818bcff54fda7b074386130af1c059ab9499..0b65354aaf64978a68836f1cb9754e4101cbc35b 100644 (file)
@@ -862,16 +862,21 @@ static int sctp_inet_supported_addrs(const struct sctp_sock *opt,
 
 /* Wrapper routine that calls the ip transmit routine. */
 static inline int sctp_v4_xmit(struct sk_buff *skb,
-                              struct sctp_transport *transport, int ipfragok)
+                              struct sctp_transport *transport)
 {
+       struct inet_sock *inet = inet_sk(skb->sk);
+
        SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, "
                          "src:%u.%u.%u.%u, dst:%u.%u.%u.%u\n",
                          __func__, skb, skb->len,
                          NIPQUAD(skb->rtable->rt_src),
                          NIPQUAD(skb->rtable->rt_dst));
 
+       inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
+                        IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
+
        SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
-       return ip_queue_xmit(skb, ipfragok);
+       return ip_queue_xmit(skb, 0);
 }
 
 static struct sctp_af sctp_af_inet;