Skip to content

Commit

Permalink
Merge master.kernel.org:/pub/scm/linux/kernel/git/vxy/lksctp-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
David S. Miller committed Jun 14, 2007
2 parents 74235a2 + 06ad391 commit 559f0a2
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 24 deletions.
7 changes: 7 additions & 0 deletions include/net/sctp/sctp.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,13 @@ static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu)
return frag;
}

static inline void sctp_assoc_pending_pmtu(struct sctp_association *asoc)
{

sctp_assoc_sync_pmtu(asoc);
asoc->pmtu_pending = 0;
}

/* Walk through a list of TLV parameters. Don't trust the
* individual parameter lengths and instead depend on
* the chunk length to indicate when to stop. Make sure
Expand Down
7 changes: 7 additions & 0 deletions include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,9 @@ struct sctp_transport {
*/
__u16 pathmaxrxt;

/* is the Path MTU update pending on this tranport */
__u8 pmtu_pending;

/* PMTU : The current known path MTU. */
__u32 pathmtu;

Expand Down Expand Up @@ -1006,6 +1009,7 @@ void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32);
void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t);
unsigned long sctp_transport_timeout(struct sctp_transport *);
void sctp_transport_reset(struct sctp_transport *);
void sctp_transport_update_pmtu(struct sctp_transport *, u32);


/* This is the structure we use to queue packets as they come into
Expand Down Expand Up @@ -1565,6 +1569,9 @@ struct sctp_association {
*/
__u16 pathmaxrxt;

/* Flag that path mtu update is pending */
__u8 pmtu_pending;

/* Association : The smallest PMTU discovered for all of the
* PMTU : peer's transport addresses.
*/
Expand Down
4 changes: 4 additions & 0 deletions net/sctp/associola.c
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,10 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
/* Get the lowest pmtu of all the transports. */
list_for_each(pos, &asoc->peer.transport_addr_list) {
t = list_entry(pos, struct sctp_transport, transports);
if (t->pmtu_pending && t->dst) {
sctp_transport_update_pmtu(t, dst_mtu(t->dst));
t->pmtu_pending = 0;
}
if (!pmtu || (t->pathmtu < pmtu))
pmtu = t->pathmtu;
}
Expand Down
24 changes: 9 additions & 15 deletions net/sctp/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,24 +367,18 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
struct sctp_transport *t, __u32 pmtu)
{
if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu))
if (!t || (t->pathmtu == pmtu))
return;

if (sock_owned_by_user(sk)) {
asoc->pmtu_pending = 1;
t->pmtu_pending = 1;
return;
}

if (t->param_flags & SPP_PMTUD_ENABLE) {
if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
printk(KERN_WARNING "%s: Reported pmtu %d too low, "
"using default minimum of %d\n",
__FUNCTION__, pmtu,
SCTP_DEFAULT_MINSEGMENT);
/* Use default minimum segment size and disable
* pmtu discovery on this transport.
*/
t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
t->param_flags = (t->param_flags & ~SPP_PMTUD) |
SPP_PMTUD_DISABLE;
} else {
t->pathmtu = pmtu;
}
/* Update transports view of the MTU */
sctp_transport_update_pmtu(t, pmtu);

/* Update association pmtu. */
sctp_assoc_sync_pmtu(asoc);
Expand Down
31 changes: 22 additions & 9 deletions net/sctp/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,12 +333,19 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
if (!sp->pf->bind_verify(sp, addr))
return -EADDRNOTAVAIL;

/* We must either be unbound, or bind to the same port. */
if (bp->port && (snum != bp->port)) {
SCTP_DEBUG_PRINTK("sctp_do_bind:"
/* We must either be unbound, or bind to the same port.
* It's OK to allow 0 ports if we are already bound.
* We'll just inhert an already bound port in this case
*/
if (bp->port) {
if (!snum)
snum = bp->port;
else if (snum != bp->port) {
SCTP_DEBUG_PRINTK("sctp_do_bind:"
" New port %d does not match existing port "
"%d.\n", snum, bp->port);
return -EINVAL;
return -EINVAL;
}
}

if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
Expand Down Expand Up @@ -1655,6 +1662,9 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto out_free;
}

if (asoc->pmtu_pending)
sctp_assoc_pending_pmtu(asoc);

/* If fragmentation is disabled and the message length exceeds the
* association fragmentation point, return EMSGSIZE. The I-D
* does not specify what this error is, but this looks like
Expand Down Expand Up @@ -3550,6 +3560,7 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
struct sock *sk = asoc->base.sk;
struct socket *sock;
struct inet_sock *inetsk;
struct sctp_af *af;
int err = 0;

/* An association cannot be branched off from an already peeled-off
Expand All @@ -3571,8 +3582,9 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
/* Make peeled-off sockets more like 1-1 accepted sockets.
* Set the daddr and initialize id to something more random
*/
af = sctp_get_af_specific(asoc->peer.primary_addr.sa.sa_family);
af->to_sk_daddr(&asoc->peer.primary_addr, sk);
inetsk = inet_sk(sock->sk);
inetsk->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
inetsk->id = asoc->next_tsn ^ jiffies;

*sockp = sock;
Expand Down Expand Up @@ -4343,11 +4355,12 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
err = -EFAULT;
goto error;
}
if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num))
return -EFAULT;
if (put_user(cnt, &((struct sctp_getaddrs __user *)optval)->addr_num)) {
err = -EFAULT;
goto error;
}
if (put_user(bytes_copied, optlen))
return -EFAULT;

err = -EFAULT;
error:
kfree(addrs);
return err;
Expand Down
39 changes: 39 additions & 0 deletions net/sctp/transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,45 @@ void sctp_transport_pmtu(struct sctp_transport *transport)
transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
}

/* this is a complete rip-off from __sk_dst_check
* the cookie is always 0 since this is how it's used in the
* pmtu code
*/
static struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t)
{
struct dst_entry *dst = t->dst;

if (dst && dst->obsolete && dst->ops->check(dst, 0) == NULL) {
dst_release(t->dst);
t->dst = NULL;
return NULL;
}

return dst;
}

void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
{
struct dst_entry *dst;

if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
printk(KERN_WARNING "%s: Reported pmtu %d too low, "
"using default minimum of %d\n",
__FUNCTION__, pmtu,
SCTP_DEFAULT_MINSEGMENT);
/* Use default minimum segment size and disable
* pmtu discovery on this transport.
*/
t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
} else {
t->pathmtu = pmtu;
}

dst = sctp_transport_dst_check(t);
if (dst)
dst->ops->update_pmtu(dst, pmtu);
}

/* Caches the dst entry and source address for a transport's destination
* address.
*/
Expand Down

0 comments on commit 559f0a2

Please sign in to comment.