Print this page
WIP to help bringup NAT flows


 159                     int level, int name, uint_t inlen,
 160                     uchar_t *invalp, uint_t *outlenp, uchar_t *outvalp,
 161                     void *thisdg_attrs, cred_t *cr);
 162 int             udp_opt_get(conn_t *connp, int level, int name,
 163                     uchar_t *ptr);
 164 static int      udp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr,
 165                     pid_t pid);
 166 static int      udp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr,
 167     pid_t pid, ip_xmit_attr_t *ixa);
 168 static int      udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin,
 169                     sin6_t *sin6, ushort_t ipversion, cred_t *cr, pid_t,
 170                     ip_xmit_attr_t *ixa);
 171 static mblk_t   *udp_prepend_hdr(conn_t *, ip_xmit_attr_t *, const ip_pkt_t *,
 172     const in6_addr_t *, const in6_addr_t *, in_port_t, uint32_t, mblk_t *,
 173     int *);
 174 static mblk_t   *udp_prepend_header_template(conn_t *, ip_xmit_attr_t *,
 175     mblk_t *, const in6_addr_t *, in_port_t, uint32_t, int *);
 176 static void     udp_ud_err(queue_t *q, mblk_t *mp, t_scalar_t err);
 177 static void     udp_ud_err_connected(conn_t *, t_scalar_t);
 178 static void     udp_tpi_unbind(queue_t *q, mblk_t *mp);
 179 static in_port_t udp_update_next_port(udp_t *udp, in_port_t port,
 180     boolean_t random);
 181 static void     udp_wput_other(queue_t *q, mblk_t *mp);
 182 static void     udp_wput_iocdata(queue_t *q, mblk_t *mp);
 183 static void     udp_wput_fallback(queue_t *q, mblk_t *mp);
 184 static size_t   udp_set_rcv_hiwat(udp_t *udp, size_t size);
 185 
 186 static void     *udp_stack_init(netstackid_t stackid, netstack_t *ns);
 187 static void     udp_stack_fini(netstackid_t stackid, void *arg);
 188 
 189 /* Common routines for TPI and socket module */
 190 static void     udp_ulp_recv(conn_t *, mblk_t *, uint_t, ip_recv_attr_t *);
 191 
 192 /* Common routine for TPI and socket module */
 193 static conn_t   *udp_do_open(cred_t *, boolean_t, int, int *);
 194 static void     udp_do_close(conn_t *);
 195 static int      udp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
 196     boolean_t);
 197 static int      udp_do_unbind(conn_t *);
 198 
 199 int             udp_getsockname(sock_lower_handle_t,
 200     struct sockaddr *, socklen_t *, cred_t *);


2636                 if (error < 0)
2637                         udp_err_ack(q, mp, -error, 0);
2638                 else
2639                         udp_err_ack(q, mp, TSYSERR, error);
2640                 return;
2641         }
2642 
2643         mp = mi_tpi_ok_ack_alloc(mp);
2644         ASSERT(mp != NULL);
2645         ASSERT(((struct T_ok_ack *)mp->b_rptr)->PRIM_type == T_OK_ACK);
2646         qreply(q, mp);
2647 }
2648 
2649 /*
2650  * Don't let port fall into the privileged range.
2651  * Since the extra privileged ports can be arbitrary we also
2652  * ensure that we exclude those from consideration.
2653  * us->us_epriv_ports is not sorted thus we loop over it until
2654  * there are no changes.
2655  */
2656 static in_port_t
2657 udp_update_next_port(udp_t *udp, in_port_t port, boolean_t random)
2658 {
2659         int i, bump;
2660         in_port_t nextport;
2661         boolean_t restart = B_FALSE;
2662         udp_stack_t *us = udp->udp_us;
2663 
2664         if (random && udp_random_anon_port != 0) {
2665                 (void) random_get_pseudo_bytes((uint8_t *)&port,
2666                     sizeof (in_port_t));
2667                 /*
2668                  * Unless changed by a sys admin, the smallest anon port
2669                  * is 32768 and the largest anon port is 65535.  It is
2670                  * very likely (50%) for the random port to be smaller
2671                  * than the smallest anon port.  When that happens,
2672                  * add port % (anon port range) to the smallest anon
2673                  * port to get the random port.  It should fall into the
2674                  * valid anon port range.
2675                  */
2676                 if ((port < us->us_smallest_anon_port) ||




 159                     int level, int name, uint_t inlen,
 160                     uchar_t *invalp, uint_t *outlenp, uchar_t *outvalp,
 161                     void *thisdg_attrs, cred_t *cr);
 162 int             udp_opt_get(conn_t *connp, int level, int name,
 163                     uchar_t *ptr);
 164 static int      udp_output_connected(conn_t *connp, mblk_t *mp, cred_t *cr,
 165                     pid_t pid);
 166 static int      udp_output_lastdst(conn_t *connp, mblk_t *mp, cred_t *cr,
 167     pid_t pid, ip_xmit_attr_t *ixa);
 168 static int      udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin,
 169                     sin6_t *sin6, ushort_t ipversion, cred_t *cr, pid_t,
 170                     ip_xmit_attr_t *ixa);
 171 static mblk_t   *udp_prepend_hdr(conn_t *, ip_xmit_attr_t *, const ip_pkt_t *,
 172     const in6_addr_t *, const in6_addr_t *, in_port_t, uint32_t, mblk_t *,
 173     int *);
 174 static mblk_t   *udp_prepend_header_template(conn_t *, ip_xmit_attr_t *,
 175     mblk_t *, const in6_addr_t *, in_port_t, uint32_t, int *);
 176 static void     udp_ud_err(queue_t *q, mblk_t *mp, t_scalar_t err);
 177 static void     udp_ud_err_connected(conn_t *, t_scalar_t);
 178 static void     udp_tpi_unbind(queue_t *q, mblk_t *mp);


 179 static void     udp_wput_other(queue_t *q, mblk_t *mp);
 180 static void     udp_wput_iocdata(queue_t *q, mblk_t *mp);
 181 static void     udp_wput_fallback(queue_t *q, mblk_t *mp);
 182 static size_t   udp_set_rcv_hiwat(udp_t *udp, size_t size);
 183 
 184 static void     *udp_stack_init(netstackid_t stackid, netstack_t *ns);
 185 static void     udp_stack_fini(netstackid_t stackid, void *arg);
 186 
 187 /* Common routines for TPI and socket module */
 188 static void     udp_ulp_recv(conn_t *, mblk_t *, uint_t, ip_recv_attr_t *);
 189 
 190 /* Common routine for TPI and socket module */
 191 static conn_t   *udp_do_open(cred_t *, boolean_t, int, int *);
 192 static void     udp_do_close(conn_t *);
 193 static int      udp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
 194     boolean_t);
 195 static int      udp_do_unbind(conn_t *);
 196 
 197 int             udp_getsockname(sock_lower_handle_t,
 198     struct sockaddr *, socklen_t *, cred_t *);


2634                 if (error < 0)
2635                         udp_err_ack(q, mp, -error, 0);
2636                 else
2637                         udp_err_ack(q, mp, TSYSERR, error);
2638                 return;
2639         }
2640 
2641         mp = mi_tpi_ok_ack_alloc(mp);
2642         ASSERT(mp != NULL);
2643         ASSERT(((struct T_ok_ack *)mp->b_rptr)->PRIM_type == T_OK_ACK);
2644         qreply(q, mp);
2645 }
2646 
2647 /*
2648  * Don't let port fall into the privileged range.
2649  * Since the extra privileged ports can be arbitrary we also
2650  * ensure that we exclude those from consideration.
2651  * us->us_epriv_ports is not sorted thus we loop over it until
2652  * there are no changes.
2653  */
2654 in_port_t
2655 udp_update_next_port(udp_t *udp, in_port_t port, boolean_t random)
2656 {
2657         int i, bump;
2658         in_port_t nextport;
2659         boolean_t restart = B_FALSE;
2660         udp_stack_t *us = udp->udp_us;
2661 
2662         if (random && udp_random_anon_port != 0) {
2663                 (void) random_get_pseudo_bytes((uint8_t *)&port,
2664                     sizeof (in_port_t));
2665                 /*
2666                  * Unless changed by a sys admin, the smallest anon port
2667                  * is 32768 and the largest anon port is 65535.  It is
2668                  * very likely (50%) for the random port to be smaller
2669                  * than the smallest anon port.  When that happens,
2670                  * add port % (anon port range) to the smallest anon
2671                  * port to get the random port.  It should fall into the
2672                  * valid anon port range.
2673                  */
2674                 if ((port < us->us_smallest_anon_port) ||