Re: [PATCH V6 2/4] sctp: Add ip option support

2018-02-18 Thread Neil Horman
On Sun, Feb 18, 2018 at 01:44:42PM +, Richard Haines wrote:
> On Fri, 2018-02-16 at 23:28 -0500, Neil Horman wrote:
> > On Fri, Feb 16, 2018 at 07:51:02PM -0200, Marcelo Ricardo Leitner
> > wrote:
> > > On Fri, Feb 16, 2018 at 03:14:35PM -0500, Neil Horman wrote:
> > > > On Fri, Feb 16, 2018 at 10:56:07AM -0200, Marcelo Ricardo Leitner
> > > > wrote:
> > > > > On Thu, Feb 15, 2018 at 09:15:40AM -0500, Neil Horman wrote:
> > > > > > On Tue, Feb 13, 2018 at 08:54:44PM +, Richard Haines
> > > > > > wrote:
> > > > > > > Add ip option support to allow LSM security modules to
> > > > > > > utilise CIPSO/IPv4
> > > > > > > and CALIPSO/IPv6 services.
> > > > > > > 
> > > > > > > Signed-off-by: Richard Haines  > > > > > > com>
> > > > > > > ---
> > > > > > >  include/net/sctp/sctp.h|  4 +++-
> > > > > > >  include/net/sctp/structs.h |  2 ++
> > > > > > >  net/sctp/chunk.c   | 12 +++-
> > > > > > >  net/sctp/ipv6.c| 42
> > > > > > > +++---
> > > > > > >  net/sctp/output.c  |  5 -
> > > > > > >  net/sctp/protocol.c| 36
> > > > > > > 
> > > > > > >  net/sctp/socket.c  | 14 ++
> > > > > > >  7 files changed, 97 insertions(+), 18 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/include/net/sctp/sctp.h
> > > > > > > b/include/net/sctp/sctp.h
> > > > > > > index f7ae6b0..25c5c87 100644
> > > > > > > --- a/include/net/sctp/sctp.h
> > > > > > > +++ b/include/net/sctp/sctp.h
> > > > > > > @@ -441,9 +441,11 @@ static inline int
> > > > > > > sctp_list_single_entry(struct list_head *head)
> > > > > > >  static inline int sctp_frag_point(const struct
> > > > > > > sctp_association *asoc, int pmtu)
> > > > > > >  {
> > > > > > >   struct sctp_sock *sp = sctp_sk(asoc->base.sk);
> > > > > > > + struct sctp_af *af = sp->pf->af;
> > > > > > >   int frag = pmtu;
> > > > > > >  
> > > > > > > - frag -= sp->pf->af->net_header_len;
> > > > > > > + frag -= af->ip_options_len(asoc->base.sk);
> > > > > > > + frag -= af->net_header_len;
> > > > > > >   frag -= sizeof(struct sctphdr) +
> > > > > > > sctp_datachk_len(>stream);
> > > > > > >  
> > > > > > >   if (asoc->user_frag)
> > > > > > > diff --git a/include/net/sctp/structs.h
> > > > > > > b/include/net/sctp/structs.h
> > > > > > > index 03e92dd..ead5fce 100644
> > > > > > > --- a/include/net/sctp/structs.h
> > > > > > > +++ b/include/net/sctp/structs.h
> > > > > > > @@ -491,6 +491,7 @@ struct sctp_af {
> > > > > > >   void(*ecn_capable)(struct sock
> > > > > > > *sk);
> > > > > > >   __u16   net_header_len;
> > > > > > >   int sockaddr_len;
> > > > > > > + int (*ip_options_len)(struct sock
> > > > > > > *sk);
> > > > > > >   sa_family_t sa_family;
> > > > > > >   struct list_head list;
> > > > > > >  };
> > > > > > > @@ -515,6 +516,7 @@ struct sctp_pf {
> > > > > > >   int (*addr_to_user)(struct sctp_sock *sk, union
> > > > > > > sctp_addr *addr);
> > > > > > >   void (*to_sk_saddr)(union sctp_addr *, struct sock
> > > > > > > *sk);
> > > > > > >   void (*to_sk_daddr)(union sctp_addr *, struct sock
> > > > > > > *sk);
> > > > > > > + void (*copy_ip_options)(struct sock *sk, struct
> > > > > > > sock *newsk);
> > > > > > >   struct sctp_af *af;
> > > > > > >  };
> > > > > > >  
> > > > > > > diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> > > > > > > index 991a530..d5c0ef7 100644
> > > > > > > --- a/net/sctp/chunk.c
> > > > > > > +++ b/net/sctp/chunk.c
> > > > > > > @@ -154,7 +154,6 @@ static void sctp_datamsg_assign(struct
> > > > > > > sctp_datamsg *msg, struct sctp_chunk *chu
> > > > > > >   chunk->msg = msg;
> > > > > > >  }
> > > > > > >  
> > > > > > > -
> > > > > > >  /* A data chunk can have a maximum payload of (2^16 -
> > > > > > > 20).  Break
> > > > > > >   * down any such message into smaller
> > > > > > > chunks.  Opportunistically, fragment
> > > > > > >   * the chunks down to the current MTU constraints.  We may
> > > > > > > get refragmented
> > > > > > > @@ -171,6 +170,8 @@ struct sctp_datamsg
> > > > > > > *sctp_datamsg_from_user(struct sctp_association *asoc,
> > > > > > >   struct list_head *pos, *temp;
> > > > > > >   struct sctp_chunk *chunk;
> > > > > > >   struct sctp_datamsg *msg;
> > > > > > > + struct sctp_sock *sp;
> > > > > > > + struct sctp_af *af;
> > > > > > >   int err;
> > > > > > >  
> > > > > > >   msg = sctp_datamsg_new(GFP_KERNEL);
> > > > > > > @@ -189,9 +190,11 @@ struct sctp_datamsg
> > > > > > > *sctp_datamsg_from_user(struct sctp_association *asoc,
> > > > > > >   /* This is the biggest possible DATA chunk that
> > > > > > > can fit into
> > > > > > >* the packet
> > > > > > >*/
> > > > > > > - max_data = asoc->pathmtu -
> > > > > > > -sctp_sk(asoc->base.sk)->pf->af-
> > > > > > > >net_header_len -
> > > > > > > -sizeof(struct sctphdr) -
> > > > > > > 

Re: [PATCH V6 2/4] sctp: Add ip option support

2018-02-18 Thread Richard Haines
On Fri, 2018-02-16 at 23:28 -0500, Neil Horman wrote:
> On Fri, Feb 16, 2018 at 07:51:02PM -0200, Marcelo Ricardo Leitner
> wrote:
> > On Fri, Feb 16, 2018 at 03:14:35PM -0500, Neil Horman wrote:
> > > On Fri, Feb 16, 2018 at 10:56:07AM -0200, Marcelo Ricardo Leitner
> > > wrote:
> > > > On Thu, Feb 15, 2018 at 09:15:40AM -0500, Neil Horman wrote:
> > > > > On Tue, Feb 13, 2018 at 08:54:44PM +, Richard Haines
> > > > > wrote:
> > > > > > Add ip option support to allow LSM security modules to
> > > > > > utilise CIPSO/IPv4
> > > > > > and CALIPSO/IPv6 services.
> > > > > > 
> > > > > > Signed-off-by: Richard Haines  > > > > > com>
> > > > > > ---
> > > > > >  include/net/sctp/sctp.h|  4 +++-
> > > > > >  include/net/sctp/structs.h |  2 ++
> > > > > >  net/sctp/chunk.c   | 12 +++-
> > > > > >  net/sctp/ipv6.c| 42
> > > > > > +++---
> > > > > >  net/sctp/output.c  |  5 -
> > > > > >  net/sctp/protocol.c| 36
> > > > > > 
> > > > > >  net/sctp/socket.c  | 14 ++
> > > > > >  7 files changed, 97 insertions(+), 18 deletions(-)
> > > > > > 
> > > > > > diff --git a/include/net/sctp/sctp.h
> > > > > > b/include/net/sctp/sctp.h
> > > > > > index f7ae6b0..25c5c87 100644
> > > > > > --- a/include/net/sctp/sctp.h
> > > > > > +++ b/include/net/sctp/sctp.h
> > > > > > @@ -441,9 +441,11 @@ static inline int
> > > > > > sctp_list_single_entry(struct list_head *head)
> > > > > >  static inline int sctp_frag_point(const struct
> > > > > > sctp_association *asoc, int pmtu)
> > > > > >  {
> > > > > > struct sctp_sock *sp = sctp_sk(asoc->base.sk);
> > > > > > +   struct sctp_af *af = sp->pf->af;
> > > > > > int frag = pmtu;
> > > > > >  
> > > > > > -   frag -= sp->pf->af->net_header_len;
> > > > > > +   frag -= af->ip_options_len(asoc->base.sk);
> > > > > > +   frag -= af->net_header_len;
> > > > > > frag -= sizeof(struct sctphdr) +
> > > > > > sctp_datachk_len(>stream);
> > > > > >  
> > > > > > if (asoc->user_frag)
> > > > > > diff --git a/include/net/sctp/structs.h
> > > > > > b/include/net/sctp/structs.h
> > > > > > index 03e92dd..ead5fce 100644
> > > > > > --- a/include/net/sctp/structs.h
> > > > > > +++ b/include/net/sctp/structs.h
> > > > > > @@ -491,6 +491,7 @@ struct sctp_af {
> > > > > > void(*ecn_capable)(struct sock
> > > > > > *sk);
> > > > > > __u16   net_header_len;
> > > > > > int sockaddr_len;
> > > > > > +   int (*ip_options_len)(struct sock
> > > > > > *sk);
> > > > > > sa_family_t sa_family;
> > > > > > struct list_head list;
> > > > > >  };
> > > > > > @@ -515,6 +516,7 @@ struct sctp_pf {
> > > > > > int (*addr_to_user)(struct sctp_sock *sk, union
> > > > > > sctp_addr *addr);
> > > > > > void (*to_sk_saddr)(union sctp_addr *, struct sock
> > > > > > *sk);
> > > > > > void (*to_sk_daddr)(union sctp_addr *, struct sock
> > > > > > *sk);
> > > > > > +   void (*copy_ip_options)(struct sock *sk, struct
> > > > > > sock *newsk);
> > > > > > struct sctp_af *af;
> > > > > >  };
> > > > > >  
> > > > > > diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> > > > > > index 991a530..d5c0ef7 100644
> > > > > > --- a/net/sctp/chunk.c
> > > > > > +++ b/net/sctp/chunk.c
> > > > > > @@ -154,7 +154,6 @@ static void sctp_datamsg_assign(struct
> > > > > > sctp_datamsg *msg, struct sctp_chunk *chu
> > > > > > chunk->msg = msg;
> > > > > >  }
> > > > > >  
> > > > > > -
> > > > > >  /* A data chunk can have a maximum payload of (2^16 -
> > > > > > 20).  Break
> > > > > >   * down any such message into smaller
> > > > > > chunks.  Opportunistically, fragment
> > > > > >   * the chunks down to the current MTU constraints.  We may
> > > > > > get refragmented
> > > > > > @@ -171,6 +170,8 @@ struct sctp_datamsg
> > > > > > *sctp_datamsg_from_user(struct sctp_association *asoc,
> > > > > > struct list_head *pos, *temp;
> > > > > > struct sctp_chunk *chunk;
> > > > > > struct sctp_datamsg *msg;
> > > > > > +   struct sctp_sock *sp;
> > > > > > +   struct sctp_af *af;
> > > > > > int err;
> > > > > >  
> > > > > > msg = sctp_datamsg_new(GFP_KERNEL);
> > > > > > @@ -189,9 +190,11 @@ struct sctp_datamsg
> > > > > > *sctp_datamsg_from_user(struct sctp_association *asoc,
> > > > > > /* This is the biggest possible DATA chunk that
> > > > > > can fit into
> > > > > >  * the packet
> > > > > >  */
> > > > > > -   max_data = asoc->pathmtu -
> > > > > > -  sctp_sk(asoc->base.sk)->pf->af-
> > > > > > >net_header_len -
> > > > > > -  sizeof(struct sctphdr) -
> > > > > > sctp_datachk_len(>stream);
> > > > > > +   sp = sctp_sk(asoc->base.sk);
> > > > > > +   af = sp->pf->af;
> > > > > > +   max_data = asoc->pathmtu - af->net_header_len -
> > > > > > +  sizeof(struct sctphdr) -
> > > > > > 

Re: [PATCH V6 2/4] sctp: Add ip option support

2018-02-16 Thread Neil Horman
On Fri, Feb 16, 2018 at 07:51:02PM -0200, Marcelo Ricardo Leitner wrote:
> On Fri, Feb 16, 2018 at 03:14:35PM -0500, Neil Horman wrote:
> > On Fri, Feb 16, 2018 at 10:56:07AM -0200, Marcelo Ricardo Leitner wrote:
> > > On Thu, Feb 15, 2018 at 09:15:40AM -0500, Neil Horman wrote:
> > > > On Tue, Feb 13, 2018 at 08:54:44PM +, Richard Haines wrote:
> > > > > Add ip option support to allow LSM security modules to utilise 
> > > > > CIPSO/IPv4
> > > > > and CALIPSO/IPv6 services.
> > > > > 
> > > > > Signed-off-by: Richard Haines 
> > > > > ---
> > > > >  include/net/sctp/sctp.h|  4 +++-
> > > > >  include/net/sctp/structs.h |  2 ++
> > > > >  net/sctp/chunk.c   | 12 +++-
> > > > >  net/sctp/ipv6.c| 42 
> > > > > +++---
> > > > >  net/sctp/output.c  |  5 -
> > > > >  net/sctp/protocol.c| 36 
> > > > >  net/sctp/socket.c  | 14 ++
> > > > >  7 files changed, 97 insertions(+), 18 deletions(-)
> > > > > 
> > > > > diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
> > > > > index f7ae6b0..25c5c87 100644
> > > > > --- a/include/net/sctp/sctp.h
> > > > > +++ b/include/net/sctp/sctp.h
> > > > > @@ -441,9 +441,11 @@ static inline int sctp_list_single_entry(struct 
> > > > > list_head *head)
> > > > >  static inline int sctp_frag_point(const struct sctp_association 
> > > > > *asoc, int pmtu)
> > > > >  {
> > > > >   struct sctp_sock *sp = sctp_sk(asoc->base.sk);
> > > > > + struct sctp_af *af = sp->pf->af;
> > > > >   int frag = pmtu;
> > > > >  
> > > > > - frag -= sp->pf->af->net_header_len;
> > > > > + frag -= af->ip_options_len(asoc->base.sk);
> > > > > + frag -= af->net_header_len;
> > > > >   frag -= sizeof(struct sctphdr) + 
> > > > > sctp_datachk_len(>stream);
> > > > >  
> > > > >   if (asoc->user_frag)
> > > > > diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> > > > > index 03e92dd..ead5fce 100644
> > > > > --- a/include/net/sctp/structs.h
> > > > > +++ b/include/net/sctp/structs.h
> > > > > @@ -491,6 +491,7 @@ struct sctp_af {
> > > > >   void(*ecn_capable)(struct sock *sk);
> > > > >   __u16   net_header_len;
> > > > >   int sockaddr_len;
> > > > > + int (*ip_options_len)(struct sock *sk);
> > > > >   sa_family_t sa_family;
> > > > >   struct list_head list;
> > > > >  };
> > > > > @@ -515,6 +516,7 @@ struct sctp_pf {
> > > > >   int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr 
> > > > > *addr);
> > > > >   void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
> > > > >   void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
> > > > > + void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
> > > > >   struct sctp_af *af;
> > > > >  };
> > > > >  
> > > > > diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> > > > > index 991a530..d5c0ef7 100644
> > > > > --- a/net/sctp/chunk.c
> > > > > +++ b/net/sctp/chunk.c
> > > > > @@ -154,7 +154,6 @@ static void sctp_datamsg_assign(struct 
> > > > > sctp_datamsg *msg, struct sctp_chunk *chu
> > > > >   chunk->msg = msg;
> > > > >  }
> > > > >  
> > > > > -
> > > > >  /* A data chunk can have a maximum payload of (2^16 - 20).  Break
> > > > >   * down any such message into smaller chunks.  Opportunistically, 
> > > > > fragment
> > > > >   * the chunks down to the current MTU constraints.  We may get 
> > > > > refragmented
> > > > > @@ -171,6 +170,8 @@ struct sctp_datamsg 
> > > > > *sctp_datamsg_from_user(struct sctp_association *asoc,
> > > > >   struct list_head *pos, *temp;
> > > > >   struct sctp_chunk *chunk;
> > > > >   struct sctp_datamsg *msg;
> > > > > + struct sctp_sock *sp;
> > > > > + struct sctp_af *af;
> > > > >   int err;
> > > > >  
> > > > >   msg = sctp_datamsg_new(GFP_KERNEL);
> > > > > @@ -189,9 +190,11 @@ struct sctp_datamsg 
> > > > > *sctp_datamsg_from_user(struct sctp_association *asoc,
> > > > >   /* This is the biggest possible DATA chunk that can fit into
> > > > >* the packet
> > > > >*/
> > > > > - max_data = asoc->pathmtu -
> > > > > -sctp_sk(asoc->base.sk)->pf->af->net_header_len -
> > > > > -sizeof(struct sctphdr) - 
> > > > > sctp_datachk_len(>stream);
> > > > > + sp = sctp_sk(asoc->base.sk);
> > > > > + af = sp->pf->af;
> > > > > + max_data = asoc->pathmtu - af->net_header_len -
> > > > > +sizeof(struct sctphdr) - 
> > > > > sctp_datachk_len(>stream) -
> > > > > +af->ip_options_len(asoc->base.sk);
> > > > >   max_data = SCTP_TRUNC4(max_data);
> > > > >  
> > > > >   /* If the the peer requested that we authenticate DATA chunks
> > > > > @@ -211,7 +214,6 @@ struct sctp_datamsg 
> > > > > *sctp_datamsg_from_user(struct sctp_association *asoc,

Re: [PATCH V6 2/4] sctp: Add ip option support

2018-02-16 Thread Marcelo Ricardo Leitner
On Fri, Feb 16, 2018 at 03:14:35PM -0500, Neil Horman wrote:
> On Fri, Feb 16, 2018 at 10:56:07AM -0200, Marcelo Ricardo Leitner wrote:
> > On Thu, Feb 15, 2018 at 09:15:40AM -0500, Neil Horman wrote:
> > > On Tue, Feb 13, 2018 at 08:54:44PM +, Richard Haines wrote:
> > > > Add ip option support to allow LSM security modules to utilise 
> > > > CIPSO/IPv4
> > > > and CALIPSO/IPv6 services.
> > > > 
> > > > Signed-off-by: Richard Haines 
> > > > ---
> > > >  include/net/sctp/sctp.h|  4 +++-
> > > >  include/net/sctp/structs.h |  2 ++
> > > >  net/sctp/chunk.c   | 12 +++-
> > > >  net/sctp/ipv6.c| 42 
> > > > +++---
> > > >  net/sctp/output.c  |  5 -
> > > >  net/sctp/protocol.c| 36 
> > > >  net/sctp/socket.c  | 14 ++
> > > >  7 files changed, 97 insertions(+), 18 deletions(-)
> > > > 
> > > > diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
> > > > index f7ae6b0..25c5c87 100644
> > > > --- a/include/net/sctp/sctp.h
> > > > +++ b/include/net/sctp/sctp.h
> > > > @@ -441,9 +441,11 @@ static inline int sctp_list_single_entry(struct 
> > > > list_head *head)
> > > >  static inline int sctp_frag_point(const struct sctp_association *asoc, 
> > > > int pmtu)
> > > >  {
> > > > struct sctp_sock *sp = sctp_sk(asoc->base.sk);
> > > > +   struct sctp_af *af = sp->pf->af;
> > > > int frag = pmtu;
> > > >  
> > > > -   frag -= sp->pf->af->net_header_len;
> > > > +   frag -= af->ip_options_len(asoc->base.sk);
> > > > +   frag -= af->net_header_len;
> > > > frag -= sizeof(struct sctphdr) + 
> > > > sctp_datachk_len(>stream);
> > > >  
> > > > if (asoc->user_frag)
> > > > diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> > > > index 03e92dd..ead5fce 100644
> > > > --- a/include/net/sctp/structs.h
> > > > +++ b/include/net/sctp/structs.h
> > > > @@ -491,6 +491,7 @@ struct sctp_af {
> > > > void(*ecn_capable)(struct sock *sk);
> > > > __u16   net_header_len;
> > > > int sockaddr_len;
> > > > +   int (*ip_options_len)(struct sock *sk);
> > > > sa_family_t sa_family;
> > > > struct list_head list;
> > > >  };
> > > > @@ -515,6 +516,7 @@ struct sctp_pf {
> > > > int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr 
> > > > *addr);
> > > > void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
> > > > void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
> > > > +   void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
> > > > struct sctp_af *af;
> > > >  };
> > > >  
> > > > diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> > > > index 991a530..d5c0ef7 100644
> > > > --- a/net/sctp/chunk.c
> > > > +++ b/net/sctp/chunk.c
> > > > @@ -154,7 +154,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg 
> > > > *msg, struct sctp_chunk *chu
> > > > chunk->msg = msg;
> > > >  }
> > > >  
> > > > -
> > > >  /* A data chunk can have a maximum payload of (2^16 - 20).  Break
> > > >   * down any such message into smaller chunks.  Opportunistically, 
> > > > fragment
> > > >   * the chunks down to the current MTU constraints.  We may get 
> > > > refragmented
> > > > @@ -171,6 +170,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> > > > sctp_association *asoc,
> > > > struct list_head *pos, *temp;
> > > > struct sctp_chunk *chunk;
> > > > struct sctp_datamsg *msg;
> > > > +   struct sctp_sock *sp;
> > > > +   struct sctp_af *af;
> > > > int err;
> > > >  
> > > > msg = sctp_datamsg_new(GFP_KERNEL);
> > > > @@ -189,9 +190,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> > > > sctp_association *asoc,
> > > > /* This is the biggest possible DATA chunk that can fit into
> > > >  * the packet
> > > >  */
> > > > -   max_data = asoc->pathmtu -
> > > > -  sctp_sk(asoc->base.sk)->pf->af->net_header_len -
> > > > -  sizeof(struct sctphdr) - 
> > > > sctp_datachk_len(>stream);
> > > > +   sp = sctp_sk(asoc->base.sk);
> > > > +   af = sp->pf->af;
> > > > +   max_data = asoc->pathmtu - af->net_header_len -
> > > > +  sizeof(struct sctphdr) - 
> > > > sctp_datachk_len(>stream) -
> > > > +  af->ip_options_len(asoc->base.sk);
> > > > max_data = SCTP_TRUNC4(max_data);
> > > >  
> > > > /* If the the peer requested that we authenticate DATA chunks
> > > > @@ -211,7 +214,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> > > > sctp_association *asoc,
> > > >  
> > > > /* Set first_len and then account for possible bundles on first 
> > > > frag */
> > > > first_len = max_data;
> > > > -
> > > > /* Check to see if we have a 

Re: [PATCH V6 2/4] sctp: Add ip option support

2018-02-16 Thread Neil Horman
On Fri, Feb 16, 2018 at 10:56:07AM -0200, Marcelo Ricardo Leitner wrote:
> On Thu, Feb 15, 2018 at 09:15:40AM -0500, Neil Horman wrote:
> > On Tue, Feb 13, 2018 at 08:54:44PM +, Richard Haines wrote:
> > > Add ip option support to allow LSM security modules to utilise CIPSO/IPv4
> > > and CALIPSO/IPv6 services.
> > > 
> > > Signed-off-by: Richard Haines 
> > > ---
> > >  include/net/sctp/sctp.h|  4 +++-
> > >  include/net/sctp/structs.h |  2 ++
> > >  net/sctp/chunk.c   | 12 +++-
> > >  net/sctp/ipv6.c| 42 
> > > +++---
> > >  net/sctp/output.c  |  5 -
> > >  net/sctp/protocol.c| 36 
> > >  net/sctp/socket.c  | 14 ++
> > >  7 files changed, 97 insertions(+), 18 deletions(-)
> > > 
> > > diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
> > > index f7ae6b0..25c5c87 100644
> > > --- a/include/net/sctp/sctp.h
> > > +++ b/include/net/sctp/sctp.h
> > > @@ -441,9 +441,11 @@ static inline int sctp_list_single_entry(struct 
> > > list_head *head)
> > >  static inline int sctp_frag_point(const struct sctp_association *asoc, 
> > > int pmtu)
> > >  {
> > >   struct sctp_sock *sp = sctp_sk(asoc->base.sk);
> > > + struct sctp_af *af = sp->pf->af;
> > >   int frag = pmtu;
> > >  
> > > - frag -= sp->pf->af->net_header_len;
> > > + frag -= af->ip_options_len(asoc->base.sk);
> > > + frag -= af->net_header_len;
> > >   frag -= sizeof(struct sctphdr) + sctp_datachk_len(>stream);
> > >  
> > >   if (asoc->user_frag)
> > > diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> > > index 03e92dd..ead5fce 100644
> > > --- a/include/net/sctp/structs.h
> > > +++ b/include/net/sctp/structs.h
> > > @@ -491,6 +491,7 @@ struct sctp_af {
> > >   void(*ecn_capable)(struct sock *sk);
> > >   __u16   net_header_len;
> > >   int sockaddr_len;
> > > + int (*ip_options_len)(struct sock *sk);
> > >   sa_family_t sa_family;
> > >   struct list_head list;
> > >  };
> > > @@ -515,6 +516,7 @@ struct sctp_pf {
> > >   int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
> > >   void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
> > >   void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
> > > + void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
> > >   struct sctp_af *af;
> > >  };
> > >  
> > > diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> > > index 991a530..d5c0ef7 100644
> > > --- a/net/sctp/chunk.c
> > > +++ b/net/sctp/chunk.c
> > > @@ -154,7 +154,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg 
> > > *msg, struct sctp_chunk *chu
> > >   chunk->msg = msg;
> > >  }
> > >  
> > > -
> > >  /* A data chunk can have a maximum payload of (2^16 - 20).  Break
> > >   * down any such message into smaller chunks.  Opportunistically, 
> > > fragment
> > >   * the chunks down to the current MTU constraints.  We may get 
> > > refragmented
> > > @@ -171,6 +170,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> > > sctp_association *asoc,
> > >   struct list_head *pos, *temp;
> > >   struct sctp_chunk *chunk;
> > >   struct sctp_datamsg *msg;
> > > + struct sctp_sock *sp;
> > > + struct sctp_af *af;
> > >   int err;
> > >  
> > >   msg = sctp_datamsg_new(GFP_KERNEL);
> > > @@ -189,9 +190,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> > > sctp_association *asoc,
> > >   /* This is the biggest possible DATA chunk that can fit into
> > >* the packet
> > >*/
> > > - max_data = asoc->pathmtu -
> > > -sctp_sk(asoc->base.sk)->pf->af->net_header_len -
> > > -sizeof(struct sctphdr) - sctp_datachk_len(>stream);
> > > + sp = sctp_sk(asoc->base.sk);
> > > + af = sp->pf->af;
> > > + max_data = asoc->pathmtu - af->net_header_len -
> > > +sizeof(struct sctphdr) - sctp_datachk_len(>stream) -
> > > +af->ip_options_len(asoc->base.sk);
> > >   max_data = SCTP_TRUNC4(max_data);
> > >  
> > >   /* If the the peer requested that we authenticate DATA chunks
> > > @@ -211,7 +214,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> > > sctp_association *asoc,
> > >  
> > >   /* Set first_len and then account for possible bundles on first frag */
> > >   first_len = max_data;
> > > -
> > >   /* Check to see if we have a pending SACK and try to let it be bundled
> > >* with this message.  Do this if we don't have any data queued already.
> > >* To check that, look at out_qlen and retransmit list.
> > > diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
> > > index e35d4f7..0b0f895 100644
> > > --- a/net/sctp/ipv6.c
> > > +++ b/net/sctp/ipv6.c
> > > @@ -427,6 +427,38 @@ static void sctp_v6_copy_addrlist(struct list_head 
> > > *addrlist,
> > >   rcu_read_unlock();
> > >  }
> > >  
> > > +/* Copy over any ip options */
> > > +static void sctp_v6_copy_ip_options(struct sock *sk, struct sock 

Re: [PATCH V6 2/4] sctp: Add ip option support

2018-02-16 Thread Marcelo Ricardo Leitner
On Thu, Feb 15, 2018 at 09:15:40AM -0500, Neil Horman wrote:
> On Tue, Feb 13, 2018 at 08:54:44PM +, Richard Haines wrote:
> > Add ip option support to allow LSM security modules to utilise CIPSO/IPv4
> > and CALIPSO/IPv6 services.
> > 
> > Signed-off-by: Richard Haines 
> > ---
> >  include/net/sctp/sctp.h|  4 +++-
> >  include/net/sctp/structs.h |  2 ++
> >  net/sctp/chunk.c   | 12 +++-
> >  net/sctp/ipv6.c| 42 +++---
> >  net/sctp/output.c  |  5 -
> >  net/sctp/protocol.c| 36 
> >  net/sctp/socket.c  | 14 ++
> >  7 files changed, 97 insertions(+), 18 deletions(-)
> > 
> > diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
> > index f7ae6b0..25c5c87 100644
> > --- a/include/net/sctp/sctp.h
> > +++ b/include/net/sctp/sctp.h
> > @@ -441,9 +441,11 @@ static inline int sctp_list_single_entry(struct 
> > list_head *head)
> >  static inline int sctp_frag_point(const struct sctp_association *asoc, int 
> > pmtu)
> >  {
> > struct sctp_sock *sp = sctp_sk(asoc->base.sk);
> > +   struct sctp_af *af = sp->pf->af;
> > int frag = pmtu;
> >  
> > -   frag -= sp->pf->af->net_header_len;
> > +   frag -= af->ip_options_len(asoc->base.sk);
> > +   frag -= af->net_header_len;
> > frag -= sizeof(struct sctphdr) + sctp_datachk_len(>stream);
> >  
> > if (asoc->user_frag)
> > diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> > index 03e92dd..ead5fce 100644
> > --- a/include/net/sctp/structs.h
> > +++ b/include/net/sctp/structs.h
> > @@ -491,6 +491,7 @@ struct sctp_af {
> > void(*ecn_capable)(struct sock *sk);
> > __u16   net_header_len;
> > int sockaddr_len;
> > +   int (*ip_options_len)(struct sock *sk);
> > sa_family_t sa_family;
> > struct list_head list;
> >  };
> > @@ -515,6 +516,7 @@ struct sctp_pf {
> > int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
> > void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
> > void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
> > +   void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
> > struct sctp_af *af;
> >  };
> >  
> > diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> > index 991a530..d5c0ef7 100644
> > --- a/net/sctp/chunk.c
> > +++ b/net/sctp/chunk.c
> > @@ -154,7 +154,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg 
> > *msg, struct sctp_chunk *chu
> > chunk->msg = msg;
> >  }
> >  
> > -
> >  /* A data chunk can have a maximum payload of (2^16 - 20).  Break
> >   * down any such message into smaller chunks.  Opportunistically, fragment
> >   * the chunks down to the current MTU constraints.  We may get refragmented
> > @@ -171,6 +170,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> > sctp_association *asoc,
> > struct list_head *pos, *temp;
> > struct sctp_chunk *chunk;
> > struct sctp_datamsg *msg;
> > +   struct sctp_sock *sp;
> > +   struct sctp_af *af;
> > int err;
> >  
> > msg = sctp_datamsg_new(GFP_KERNEL);
> > @@ -189,9 +190,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> > sctp_association *asoc,
> > /* This is the biggest possible DATA chunk that can fit into
> >  * the packet
> >  */
> > -   max_data = asoc->pathmtu -
> > -  sctp_sk(asoc->base.sk)->pf->af->net_header_len -
> > -  sizeof(struct sctphdr) - sctp_datachk_len(>stream);
> > +   sp = sctp_sk(asoc->base.sk);
> > +   af = sp->pf->af;
> > +   max_data = asoc->pathmtu - af->net_header_len -
> > +  sizeof(struct sctphdr) - sctp_datachk_len(>stream) -
> > +  af->ip_options_len(asoc->base.sk);
> > max_data = SCTP_TRUNC4(max_data);
> >  
> > /* If the the peer requested that we authenticate DATA chunks
> > @@ -211,7 +214,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> > sctp_association *asoc,
> >  
> > /* Set first_len and then account for possible bundles on first frag */
> > first_len = max_data;
> > -
> > /* Check to see if we have a pending SACK and try to let it be bundled
> >  * with this message.  Do this if we don't have any data queued already.
> >  * To check that, look at out_qlen and retransmit list.
> > diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
> > index e35d4f7..0b0f895 100644
> > --- a/net/sctp/ipv6.c
> > +++ b/net/sctp/ipv6.c
> > @@ -427,6 +427,38 @@ static void sctp_v6_copy_addrlist(struct list_head 
> > *addrlist,
> > rcu_read_unlock();
> >  }
> >  
> > +/* Copy over any ip options */
> > +static void sctp_v6_copy_ip_options(struct sock *sk, struct sock *newsk)
> > +{
> > +   struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
> > +   struct ipv6_txoptions *opt;
> > +
> > +   newnp = inet6_sk(newsk);
> > +
> > +   rcu_read_lock();
> > +   opt = rcu_dereference(np->opt);
> > +   if (opt)
> > 

Re: [PATCH V6 2/4] sctp: Add ip option support

2018-02-15 Thread Neil Horman
On Tue, Feb 13, 2018 at 08:54:44PM +, Richard Haines wrote:
> Add ip option support to allow LSM security modules to utilise CIPSO/IPv4
> and CALIPSO/IPv6 services.
> 
> Signed-off-by: Richard Haines 
> ---
>  include/net/sctp/sctp.h|  4 +++-
>  include/net/sctp/structs.h |  2 ++
>  net/sctp/chunk.c   | 12 +++-
>  net/sctp/ipv6.c| 42 +++---
>  net/sctp/output.c  |  5 -
>  net/sctp/protocol.c| 36 
>  net/sctp/socket.c  | 14 ++
>  7 files changed, 97 insertions(+), 18 deletions(-)
> 
> diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
> index f7ae6b0..25c5c87 100644
> --- a/include/net/sctp/sctp.h
> +++ b/include/net/sctp/sctp.h
> @@ -441,9 +441,11 @@ static inline int sctp_list_single_entry(struct 
> list_head *head)
>  static inline int sctp_frag_point(const struct sctp_association *asoc, int 
> pmtu)
>  {
>   struct sctp_sock *sp = sctp_sk(asoc->base.sk);
> + struct sctp_af *af = sp->pf->af;
>   int frag = pmtu;
>  
> - frag -= sp->pf->af->net_header_len;
> + frag -= af->ip_options_len(asoc->base.sk);
> + frag -= af->net_header_len;
>   frag -= sizeof(struct sctphdr) + sctp_datachk_len(>stream);
>  
>   if (asoc->user_frag)
> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> index 03e92dd..ead5fce 100644
> --- a/include/net/sctp/structs.h
> +++ b/include/net/sctp/structs.h
> @@ -491,6 +491,7 @@ struct sctp_af {
>   void(*ecn_capable)(struct sock *sk);
>   __u16   net_header_len;
>   int sockaddr_len;
> + int (*ip_options_len)(struct sock *sk);
>   sa_family_t sa_family;
>   struct list_head list;
>  };
> @@ -515,6 +516,7 @@ struct sctp_pf {
>   int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
>   void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
>   void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
> + void (*copy_ip_options)(struct sock *sk, struct sock *newsk);
>   struct sctp_af *af;
>  };
>  
> diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> index 991a530..d5c0ef7 100644
> --- a/net/sctp/chunk.c
> +++ b/net/sctp/chunk.c
> @@ -154,7 +154,6 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, 
> struct sctp_chunk *chu
>   chunk->msg = msg;
>  }
>  
> -
>  /* A data chunk can have a maximum payload of (2^16 - 20).  Break
>   * down any such message into smaller chunks.  Opportunistically, fragment
>   * the chunks down to the current MTU constraints.  We may get refragmented
> @@ -171,6 +170,8 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> sctp_association *asoc,
>   struct list_head *pos, *temp;
>   struct sctp_chunk *chunk;
>   struct sctp_datamsg *msg;
> + struct sctp_sock *sp;
> + struct sctp_af *af;
>   int err;
>  
>   msg = sctp_datamsg_new(GFP_KERNEL);
> @@ -189,9 +190,11 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> sctp_association *asoc,
>   /* This is the biggest possible DATA chunk that can fit into
>* the packet
>*/
> - max_data = asoc->pathmtu -
> -sctp_sk(asoc->base.sk)->pf->af->net_header_len -
> -sizeof(struct sctphdr) - sctp_datachk_len(>stream);
> + sp = sctp_sk(asoc->base.sk);
> + af = sp->pf->af;
> + max_data = asoc->pathmtu - af->net_header_len -
> +sizeof(struct sctphdr) - sctp_datachk_len(>stream) -
> +af->ip_options_len(asoc->base.sk);
>   max_data = SCTP_TRUNC4(max_data);
>  
>   /* If the the peer requested that we authenticate DATA chunks
> @@ -211,7 +214,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct 
> sctp_association *asoc,
>  
>   /* Set first_len and then account for possible bundles on first frag */
>   first_len = max_data;
> -
>   /* Check to see if we have a pending SACK and try to let it be bundled
>* with this message.  Do this if we don't have any data queued already.
>* To check that, look at out_qlen and retransmit list.
> diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
> index e35d4f7..0b0f895 100644
> --- a/net/sctp/ipv6.c
> +++ b/net/sctp/ipv6.c
> @@ -427,6 +427,38 @@ static void sctp_v6_copy_addrlist(struct list_head 
> *addrlist,
>   rcu_read_unlock();
>  }
>  
> +/* Copy over any ip options */
> +static void sctp_v6_copy_ip_options(struct sock *sk, struct sock *newsk)
> +{
> + struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
> + struct ipv6_txoptions *opt;
> +
> + newnp = inet6_sk(newsk);
> +
> + rcu_read_lock();
> + opt = rcu_dereference(np->opt);
> + if (opt)
> + opt = ipv6_dup_options(newsk, opt);
do you want to print a warning here in the event the allocation
for the dup operation fails?

> + RCU_INIT_POINTER(newnp->opt, opt);

Re: [PATCH V6 2/4] sctp: Add ip option support

2018-02-14 Thread Marcelo Ricardo Leitner
Hi,

On Tue, Feb 13, 2018 at 08:54:44PM +, Richard Haines wrote:
...
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index bf271f8..8307968 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -3138,6 +3138,7 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, 
> char __user *optval, unsign
>  static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, 
> unsigned int optlen)
>  {
>   struct sctp_sock *sp = sctp_sk(sk);
> + struct sctp_af *af = sp->pf->af;
>   struct sctp_assoc_value params;
>   struct sctp_association *asoc;
>   int val;
> @@ -3159,10 +3160,13 @@ static int sctp_setsockopt_maxseg(struct sock *sk, 
> char __user *optval, unsigned
>   return -EINVAL;
>   }
>  
> + asoc = sctp_id2assoc(sk, params.assoc_id);
> +
>   if (val) {
>   int min_len, max_len;
>  
> - min_len = SCTP_DEFAULT_MINSEGMENT - sp->pf->af->net_header_len;
> + min_len = SCTP_DEFAULT_MINSEGMENT - af->net_header_len;
> + min_len -= af->ip_options_len(asoc->base.sk);

We have an issue here. asoc may be NULL, in case the user supplied
asoc id is invalid. Then if it also specified the maxseg 'val', it
would trigger a NULL deref here.

You don't need to find the asoc, to then get to the socket. You can
use the sk function parameter, it's the same value here. Then you
don't need to move the sctp_id2assoc() call.

>   min_len -= sizeof(struct sctphdr) +
>  sizeof(struct sctp_data_chunk);
>  
> @@ -3172,10 +3176,10 @@ static int sctp_setsockopt_maxseg(struct sock *sk, 
> char __user *optval, unsigned
>   return -EINVAL;
>   }
>  
> - asoc = sctp_id2assoc(sk, params.assoc_id);
>   if (asoc) {
>   if (val == 0) {
> - val = asoc->pathmtu - sp->pf->af->net_header_len;
> + val = asoc->pathmtu - af->net_header_len;
> + val -= af->ip_options_len(asoc->base.sk);

You may use sk directly here too.

Other than these, LGTM.

>   val -= sizeof(struct sctphdr) +
>  sctp_datachk_len(>stream);
>   }
> @@ -5087,9 +5091,11 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, 
> struct socket **sockp)
>   sctp_copy_sock(sock->sk, sk, asoc);
>  
>   /* Make peeled-off sockets more like 1-1 accepted sockets.
> -  * Set the daddr and initialize id to something more random
> +  * Set the daddr and initialize id to something more random and also
> +  * copy over any ip options.
>*/
>   sp->pf->to_sk_daddr(>peer.primary_addr, sk);
> + sp->pf->copy_ip_options(sk, sock->sk);
>  
>   /* Populate the fields of the newsk from the oldsk and migrate the
>* asoc to the newsk.
> -- 
> 2.14.3
>