Author: tuexen
Date: Sun May  1 21:48:55 2016
New Revision: 298902
URL: https://svnweb.freebsd.org/changeset/base/298902

Log:
  When a client uses UDP encapsulation and lists IP addresses in the INIT
  chunk, enable UDP encapsulation for all those addresses.
  This helps clients using a userland stack to support multihoming if
  they are not behind a NAT.
  
  MFC after: 1 week

Modified:
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_pcb.h
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet6/sctp6_usrreq.c

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c       Sun May  1 21:17:30 2016        
(r298901)
+++ head/sys/netinet/sctp_input.c       Sun May  1 21:48:55 2016        
(r298902)
@@ -465,7 +465,7 @@ sctp_process_init_ack(struct mbuf *m, in
        /* load all addresses */
        if ((retval = sctp_load_addresses_from_init(stcb, m,
            (offset + sizeof(struct sctp_init_chunk)), initack_limit,
-           src, dst, NULL))) {
+           src, dst, NULL, stcb->asoc.port))) {
                op_err = 
sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
                    "Problem with address parameters");
                SCTPDBG(SCTP_DEBUG_INPUT1,
@@ -1672,7 +1672,7 @@ sctp_process_cookie_existing(struct mbuf
                 */
                if (sctp_load_addresses_from_init(stcb, m,
                    init_offset + sizeof(struct sctp_init_chunk),
-                   initack_offset, src, dst, init_src)) {
+                   initack_offset, src, dst, init_src, stcb->asoc.port)) {
                        if (how_indx < sizeof(asoc->cookie_how))
                                asoc->cookie_how[how_indx] = 4;
                        return (NULL);
@@ -1799,7 +1799,7 @@ sctp_process_cookie_existing(struct mbuf
                }
                if (sctp_load_addresses_from_init(stcb, m,
                    init_offset + sizeof(struct sctp_init_chunk),
-                   initack_offset, src, dst, init_src)) {
+                   initack_offset, src, dst, init_src, stcb->asoc.port)) {
                        if (how_indx < sizeof(asoc->cookie_how))
                                asoc->cookie_how[how_indx] = 10;
                        return (NULL);
@@ -2011,7 +2011,7 @@ sctp_process_cookie_existing(struct mbuf
 
                if (sctp_load_addresses_from_init(stcb, m,
                    init_offset + sizeof(struct sctp_init_chunk),
-                   initack_offset, src, dst, init_src)) {
+                   initack_offset, src, dst, init_src, stcb->asoc.port)) {
                        if (how_indx < sizeof(asoc->cookie_how))
                                asoc->cookie_how[how_indx] = 14;
 
@@ -2123,6 +2123,7 @@ sctp_process_cookie_new(struct mbuf *m, 
        stcb = sctp_aloc_assoc(inp, init_src, &error,
            ntohl(initack_cp->init.initiate_tag), vrf_id,
            ntohs(initack_cp->init.num_outbound_streams),
+           port,
            (struct thread *)NULL
            );
        if (stcb == NULL) {
@@ -2212,7 +2213,7 @@ sctp_process_cookie_new(struct mbuf *m, 
        /* load all addresses */
        if (sctp_load_addresses_from_init(stcb, m,
            init_offset + sizeof(struct sctp_init_chunk), initack_offset,
-           src, dst, init_src)) {
+           src, dst, init_src, port)) {
                atomic_add_int(&stcb->asoc.refcnt, 1);
 #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
                SCTP_TCB_UNLOCK(stcb);
@@ -2371,12 +2372,6 @@ sctp_process_cookie_new(struct mbuf *m, 
                (*netp)->RTO = sctp_calculate_rto(stcb, asoc, *netp,
                    &cookie->time_entered, sctp_align_unsafe_makecopy,
                    SCTP_RTT_FROM_NON_DATA);
-#if defined(INET) || defined(INET6)
-               if (((*netp)->port == 0) && (port != 0)) {
-                       sctp_pathmtu_adjustment(stcb, (uint16_t) ((*netp)->mtu 
- sizeof(struct udphdr)));
-               }
-               (*netp)->port = port;
-#endif
        }
        /* respond with a COOKIE-ACK */
        sctp_send_cookie_ack(stcb);
@@ -2718,7 +2713,7 @@ sctp_handle_cookie_echo(struct mbuf *m, 
         */
        if (netl == NULL) {
                /* TSNH! Huh, why do I need to add this address here? */
-               if (sctp_add_remote_addr(*stcb, to, NULL, (*stcb)->asoc.port,
+               if (sctp_add_remote_addr(*stcb, to, NULL, port,
                    SCTP_DONOT_SETSCOPE, SCTP_IN_COOKIE_PROC)) {
                        return (NULL);
                }

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c      Sun May  1 21:17:30 2016        
(r298901)
+++ head/sys/netinet/sctp_output.c      Sun May  1 21:48:55 2016        
(r298902)
@@ -12765,8 +12765,8 @@ sctp_lower_sosend(struct socket *so,
 #endif
                        stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
                            inp->sctp_ep.pre_open_stream_count,
-                           p
-                           );
+                           inp->sctp_ep.port,
+                           p);
                        if (stcb == NULL) {
                                /* Error is setup for us in the call */
                                goto out_unlocked;

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c Sun May  1 21:17:30 2016        (r298901)
+++ head/sys/netinet/sctp_pcb.c Sun May  1 21:48:55 2016        (r298902)
@@ -4045,7 +4045,7 @@ sctp_add_remote_addr(struct sctp_tcb *st
                stcb->asoc.smallest_mtu = net->mtu;
        }
        if (stcb->asoc.smallest_mtu > net->mtu) {
-               stcb->asoc.smallest_mtu = net->mtu;
+               sctp_pathmtu_adjustment(stcb, net->mtu);
        }
 #ifdef INET6
        if (newaddr->sa_family == AF_INET6) {
@@ -4191,7 +4191,7 @@ try_again:
 struct sctp_tcb *
 sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
     int *error, uint32_t override_tag, uint32_t vrf_id,
-    uint16_t o_streams,
+    uint16_t o_streams, uint16_t port,
     struct thread *p
 )
 {
@@ -4384,7 +4384,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, 
        LIST_INSERT_HEAD(head, stcb, sctp_asocs);
        SCTP_INP_INFO_WUNLOCK();
 
-       if ((err = sctp_add_remote_addr(stcb, firstaddr, NULL, asoc->port, 
SCTP_DO_SETSCOPE, SCTP_ALLOC_ASOC))) {
+       if ((err = sctp_add_remote_addr(stcb, firstaddr, NULL, port, 
SCTP_DO_SETSCOPE, SCTP_ALLOC_ASOC))) {
                /* failure.. memory error? */
                if (asoc->strmout) {
                        SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
@@ -6068,7 +6068,7 @@ int
 sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
     int offset, int limit,
     struct sockaddr *src, struct sockaddr *dst,
-    struct sockaddr *altsa)
+    struct sockaddr *altsa, uint16_t port)
 {
        /*
         * grub through the INIT pulling addresses and loading them to the
@@ -6159,7 +6159,7 @@ sctp_load_addresses_from_init(struct sct
 #ifdef INET
                case AF_INET:
                        if (stcb->asoc.scope.ipv4_addr_legal) {
-                               if (sctp_add_remote_addr(stcb, sa, NULL, 
stcb->asoc.port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) {
+                               if (sctp_add_remote_addr(stcb, sa, NULL, port, 
SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_2)) {
                                        return (-1);
                                }
                        }
@@ -6168,7 +6168,7 @@ sctp_load_addresses_from_init(struct sct
 #ifdef INET6
                case AF_INET6:
                        if (stcb->asoc.scope.ipv6_addr_legal) {
-                               if (sctp_add_remote_addr(stcb, sa, NULL, 
stcb->asoc.port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
+                               if (sctp_add_remote_addr(stcb, sa, NULL, port, 
SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_3)) {
                                        return (-2);
                                }
                        }
@@ -6253,7 +6253,7 @@ sctp_load_addresses_from_init(struct sct
                                                /* the assoc was freed? */
                                                return (-7);
                                        }
-                                       if (sctp_add_remote_addr(stcb, sa, 
NULL, stcb->asoc.port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_4)) {
+                                       if (sctp_add_remote_addr(stcb, sa, 
NULL, port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_4)) {
                                                return (-8);
                                        }
                                } else if (stcb_tmp == stcb) {
@@ -6348,7 +6348,7 @@ sctp_load_addresses_from_init(struct sct
                                         * we must add the address, no scope
                                         * set
                                         */
-                                       if (sctp_add_remote_addr(stcb, sa, 
NULL, stcb->asoc.port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_5)) {
+                                       if (sctp_add_remote_addr(stcb, sa, 
NULL, port, SCTP_DONOT_SETSCOPE, SCTP_LOAD_ADDR_5)) {
                                                return (-17);
                                        }
                                } else if (stcb_tmp == stcb) {

Modified: head/sys/netinet/sctp_pcb.h
==============================================================================
--- head/sys/netinet/sctp_pcb.h Sun May  1 21:17:30 2016        (r298901)
+++ head/sys/netinet/sctp_pcb.h Sun May  1 21:48:55 2016        (r298902)
@@ -585,7 +585,7 @@ void sctp_inpcb_free(struct sctp_inpcb *
 
 struct sctp_tcb *
 sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
-    int *, uint32_t, uint32_t, uint16_t, struct thread *);
+    int *, uint32_t, uint32_t, uint16_t, uint16_t, struct thread *);
 
 int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int);
 
@@ -616,7 +616,7 @@ void sctp_del_local_addr_restricted(stru
 
 int
 sctp_load_addresses_from_init(struct sctp_tcb *, struct mbuf *, int, int,
-    struct sockaddr *, struct sockaddr *, struct sockaddr *);
+    struct sockaddr *, struct sockaddr *, struct sockaddr *, uint16_t);
 
 int
 sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *,

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c      Sun May  1 21:17:30 2016        
(r298901)
+++ head/sys/netinet/sctp_usrreq.c      Sun May  1 21:48:55 2016        
(r298902)
@@ -1474,6 +1474,7 @@ sctp_do_connect_x(struct socket *so, str
        /* We are GOOD to go */
        stcb = sctp_aloc_assoc(inp, sa, &error, 0, vrf_id,
            inp->sctp_ep.pre_open_stream_count,
+           inp->sctp_ep.port,
            (struct thread *)p
            );
        if (stcb == NULL) {
@@ -6999,7 +7000,9 @@ sctp_connect(struct socket *so, struct s
        }
        vrf_id = inp->def_vrf_id;
        /* We are GOOD to go */
-       stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, 
inp->sctp_ep.pre_open_stream_count, p);
+       stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
+           inp->sctp_ep.pre_open_stream_count,
+           inp->sctp_ep.port, p);
        if (stcb == NULL) {
                /* Gak! no memory */
                goto out_now;

Modified: head/sys/netinet6/sctp6_usrreq.c
==============================================================================
--- head/sys/netinet6/sctp6_usrreq.c    Sun May  1 21:17:30 2016        
(r298901)
+++ head/sys/netinet6/sctp6_usrreq.c    Sun May  1 21:48:55 2016        
(r298902)
@@ -919,7 +919,9 @@ sctp6_connect(struct socket *so, struct 
                return (EALREADY);
        }
        /* We are GOOD to go */
-       stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, 
inp->sctp_ep.pre_open_stream_count, p);
+       stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
+           inp->sctp_ep.pre_open_stream_count,
+           inp->sctp_ep.port, p);
        SCTP_ASOC_CREATE_UNLOCK(inp);
        if (stcb == NULL) {
                /* Gak! no memory */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to