aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-08-04 00:15:08 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-04 00:15:08 -0400
commitf880374c2fe37aad3fa62253a4bc125d7a933aad (patch)
tree7ff62dfd04689f09c0c27b24340479fc92de5e0d
parentcfb266c0ee0ea0b7bfa8189e3a3a80344dec6112 (diff)
sctp: Drop ipfargok in sctp_xmit function
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>
-rw-r--r--include/net/sctp/structs.h3
-rw-r--r--net/sctp/ipv6.c8
-rw-r--r--net/sctp/output.c6
-rw-r--r--net/sctp/protocol.c9
4 files changed, 15 insertions, 11 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 535a18f57a13..ab1c472ea753 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -524,8 +524,7 @@ static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id,
524 */ 524 */
525struct sctp_af { 525struct sctp_af {
526 int (*sctp_xmit) (struct sk_buff *skb, 526 int (*sctp_xmit) (struct sk_buff *skb,
527 struct sctp_transport *, 527 struct sctp_transport *);
528 int ipfragok);
529 int (*setsockopt) (struct sock *sk, 528 int (*setsockopt) (struct sock *sk,
530 int level, 529 int level,
531 int optname, 530 int optname,
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index a238d6834b33..483a01d0740a 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -195,8 +195,7 @@ out:
195} 195}
196 196
197/* Based on tcp_v6_xmit() in tcp_ipv6.c. */ 197/* Based on tcp_v6_xmit() in tcp_ipv6.c. */
198static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport, 198static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
199 int ipfragok)
200{ 199{
201 struct sock *sk = skb->sk; 200 struct sock *sk = skb->sk;
202 struct ipv6_pinfo *np = inet6_sk(sk); 201 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -231,7 +230,10 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
231 230
232 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); 231 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
233 232
234 return ip6_xmit(sk, skb, &fl, np->opt, ipfragok); 233 if (!(transport->param_flags & SPP_PMTUD_ENABLE))
234 skb->local_df = 1;
235
236 return ip6_xmit(sk, skb, &fl, np->opt, 0);
235} 237}
236 238
237/* Returns the dst cache entry for the given source and destination ip 239/* Returns the dst cache entry for the given source and destination ip
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 45684646b1db..0dc4a7dfb234 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -586,10 +586,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
586 SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n", 586 SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
587 nskb->len); 587 nskb->len);
588 588
589 if (tp->param_flags & SPP_PMTUD_ENABLE) 589 nskb->local_df = packet->ipfragok;
590 (*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok); 590 (*tp->af_specific->sctp_xmit)(nskb, tp);
591 else
592 (*tp->af_specific->sctp_xmit)(nskb, tp, 1);
593 591
594out: 592out:
595 packet->size = packet->overhead; 593 packet->size = packet->overhead;
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index a6e0818bcff5..0b65354aaf64 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -862,16 +862,21 @@ static int sctp_inet_supported_addrs(const struct sctp_sock *opt,
862 862
863/* Wrapper routine that calls the ip transmit routine. */ 863/* Wrapper routine that calls the ip transmit routine. */
864static inline int sctp_v4_xmit(struct sk_buff *skb, 864static inline int sctp_v4_xmit(struct sk_buff *skb,
865 struct sctp_transport *transport, int ipfragok) 865 struct sctp_transport *transport)
866{ 866{
867 struct inet_sock *inet = inet_sk(skb->sk);
868
867 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, " 869 SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, "
868 "src:%u.%u.%u.%u, dst:%u.%u.%u.%u\n", 870 "src:%u.%u.%u.%u, dst:%u.%u.%u.%u\n",
869 __func__, skb, skb->len, 871 __func__, skb, skb->len,
870 NIPQUAD(skb->rtable->rt_src), 872 NIPQUAD(skb->rtable->rt_src),
871 NIPQUAD(skb->rtable->rt_dst)); 873 NIPQUAD(skb->rtable->rt_dst));
872 874
875 inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
876 IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
877
873 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); 878 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
874 return ip_queue_xmit(skb, ipfragok); 879 return ip_queue_xmit(skb, 0);
875} 880}
876 881
877static struct sctp_af sctp_af_inet; 882static struct sctp_af sctp_af_inet;