Loading include/net/sctp/sctp.h +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading include/net/sctp/structs.h +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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. */ Loading net/sctp/associola.c +4 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading net/sctp/input.c +9 −15 Original line number Diff line number Diff line Loading @@ -367,25 +367,19 @@ 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 (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; if (sock_owned_by_user(sk)) { asoc->pmtu_pending = 1; t->pmtu_pending = 1; return; } if (t->param_flags & SPP_PMTUD_ENABLE) { /* Update transports view of the MTU */ sctp_transport_update_pmtu(t, pmtu); /* Update association pmtu. */ sctp_assoc_sync_pmtu(asoc); } Loading net/sctp/socket.c +22 −9 Original line number Diff line number Diff line Loading @@ -333,13 +333,20 @@ 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)) { /* 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; } } if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) return -EACCES; Loading Loading @@ -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 Loading Loading @@ -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 Loading @@ -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; Loading Loading @@ -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; Loading Loading
include/net/sctp/sctp.h +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
include/net/sctp/structs.h +7 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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. */ Loading
net/sctp/associola.c +4 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading
net/sctp/input.c +9 −15 Original line number Diff line number Diff line Loading @@ -367,25 +367,19 @@ 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 (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; if (sock_owned_by_user(sk)) { asoc->pmtu_pending = 1; t->pmtu_pending = 1; return; } if (t->param_flags & SPP_PMTUD_ENABLE) { /* Update transports view of the MTU */ sctp_transport_update_pmtu(t, pmtu); /* Update association pmtu. */ sctp_assoc_sync_pmtu(asoc); } Loading
net/sctp/socket.c +22 −9 Original line number Diff line number Diff line Loading @@ -333,13 +333,20 @@ 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)) { /* 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; } } if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) return -EACCES; Loading Loading @@ -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 Loading Loading @@ -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 Loading @@ -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; Loading Loading @@ -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; Loading