Date: Mon, 10 Jan 2011 03:56:58 +0000 (UTC) From: Jeff Roberson <jeff@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r217216 - projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp Message-ID: <201101100356.p0A3uw5P066293@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jeff Date: Mon Jan 10 03:56:58 2011 New Revision: 217216 URL: http://svn.freebsd.org/changeset/base/217216 Log: - Always store lport in network byte order. - Always initialize lport from an accepted socket. - Provide a pcbinfo sysctl so netstat can display sdp sockets alongside tcp and udp. Sponsored by: Isilon Systems, iX Systems, and Panasas. Modified: projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp.h projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_cma.c projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_dbg.h projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c Modified: projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp.h ============================================================================== --- projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp.h Mon Jan 10 03:55:45 2011 (r217215) +++ projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp.h Mon Jan 10 03:56:58 2011 (r217216) @@ -30,9 +30,11 @@ #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/in_var.h> +#include <netinet/in_pcb.h> #include <netinet/tcp.h> #include <netinet/tcp_fsm.h> #include <netinet/tcp_timer.h> +#include <netinet/tcp_var.h> #include <linux/device.h> #include <linux/err.h> Modified: projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_cma.c ============================================================================== --- projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_cma.c Mon Jan 10 03:55:45 2011 (r217215) +++ projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_cma.c Mon Jan 10 03:56:58 2011 (r217216) @@ -136,6 +136,7 @@ static int sdp_connect_handler(struct socket *sk, struct rdma_cm_id *id, struct rdma_cm_event *event) { + struct sockaddr_in *src_addr; struct sockaddr_in *dst_addr; struct socket *child; const struct sdp_hh *h; @@ -164,8 +165,10 @@ sdp_connect_handler(struct socket *sk, s ssk->socket = child; ssk->cred = crhold(child->so_cred); dst_addr = (struct sockaddr_in *)&id->route.addr.dst_addr; + src_addr = (struct sockaddr_in *)&id->route.addr.src_addr; ssk->fport = dst_addr->sin_port; ssk->faddr = dst_addr->sin_addr.s_addr; + ssk->lport = src_addr->sin_port; ssk->max_bufs = ntohs(h->bsdh.bufs); atomic_set(&ssk->tx_ring.credits, ssk->max_bufs); ssk->min_bufs = tx_credits(ssk) / 4; Modified: projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_dbg.h ============================================================================== --- projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_dbg.h Mon Jan 10 03:55:45 2011 (r217215) +++ projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_dbg.h Mon Jan 10 03:56:58 2011 (r217216) @@ -10,7 +10,7 @@ do { \ printk(level "%s:%d %p sdp_sock(%d:%d %d:%d): " format "\n", \ func, line, sk ? sdp_sk(sk) : NULL, \ curproc->p_pid, PCPU_GET(cpuid), \ - (sk) && sdp_sk(sk) ? sdp_sk(sk)->lport : -1, \ + (sk) && sdp_sk(sk) ? ntohs(sdp_sk(sk)->lport) : -1, \ (sk) && sdp_sk(sk) ? ntohs(sdp_sk(sk)->fport) : -1, ## arg); \ } while (0) #define sdp_printk(level, sk, format, arg...) \ Modified: projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c ============================================================================== --- projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c Mon Jan 10 03:55:45 2011 (r217215) +++ projects/ofed/head/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c Mon Jan 10 03:56:58 2011 (r217216) @@ -97,6 +97,8 @@ MALLOC_DEFINE(M_SDP, "sdp", "Socket Dire u_long sdp_sendspace = 1024*32; u_long sdp_recvspace = 1024*64; +static int sdp_count; + static int sdp_pcbbind(struct sdp_sock *ssk, struct sockaddr *nam, struct ucred *cred) { @@ -132,7 +134,7 @@ sdp_pcbbind(struct sdp_sock *ssk, struct } else { sin = (struct sockaddr_in *)&ssk->id->route.addr.src_addr; ssk->laddr = sin->sin_addr.s_addr; - ssk->lport = ntohs(sin->sin_port); + ssk->lport = sin->sin_port; } return (error); } @@ -160,6 +162,7 @@ sdp_pcbfree(struct sdp_sock *ssk) ssk->flags |= SDP_DESTROY; SDP_WUNLOCK(ssk); SDP_LIST_WLOCK(); + sdp_count--; LIST_REMOVE(ssk, list); SDP_LIST_WUNLOCK(); crfree(ssk->cred); @@ -384,6 +387,7 @@ sdp_attach(struct socket *so, int proto, ssk->state = TCPS_CLOSED; SDP_LIST_WLOCK(); LIST_INSERT_HEAD(&sdp_list, ssk, list); + sdp_count++; SDP_LIST_WUNLOCK(); if ((so->so_options & SO_LINGER) && so->so_linger == 0) so->so_linger = TCP_LINGERTIME; @@ -498,7 +502,7 @@ sdp_start_connect(struct sdp_sock *ssk, src.sin_family = AF_INET; src.sin_len = sizeof(src); bzero(&src.sin_zero, sizeof(src.sin_zero)); - src.sin_port = htons(ssk->lport); + src.sin_port = ssk->lport; src.sin_addr.s_addr = ssk->laddr; soisconnecting(so); SDP_WUNLOCK(ssk); @@ -1693,6 +1697,111 @@ sdp_dev_rem(struct ib_device *device) struct ib_client sdp_client = { .name = "sdp", .add = sdp_dev_add, .remove = sdp_dev_rem }; + +static int +sdp_pcblist(SYSCTL_HANDLER_ARGS) +{ + int error, n, i; + struct sdp_sock *ssk; + struct xinpgen xig; + + /* + * The process of preparing the TCB list is too time-consuming and + * resource-intensive to repeat twice on every request. + */ + if (req->oldptr == NULL) { + n = sdp_count; + n += imax(n / 8, 10); + req->oldidx = 2 * (sizeof xig) + n * sizeof(struct xtcpcb); + return (0); + } + + if (req->newptr != NULL) + return (EPERM); + + /* + * OK, now we're committed to doing something. + */ + SDP_LIST_RLOCK(); + n = sdp_count; + SDP_LIST_RUNLOCK(); + + error = sysctl_wire_old_buffer(req, 2 * (sizeof xig) + + n * sizeof(struct xtcpcb)); + if (error != 0) + return (error); + + xig.xig_len = sizeof xig; + xig.xig_count = n; + xig.xig_gen = 0; + xig.xig_sogen = so_gencnt; + error = SYSCTL_OUT(req, &xig, sizeof xig); + if (error) + return (error); + + SDP_LIST_RLOCK(); + for (ssk = LIST_FIRST(&sdp_list), i = 0; + ssk != NULL && i < n; ssk = LIST_NEXT(ssk, list)) { + struct xtcpcb xt; + + SDP_RLOCK(ssk); + if (ssk->flags & SDP_TIMEWAIT) { + if (ssk->cred != NULL) + error = cr_cansee(req->td->td_ucred, + ssk->cred); + else + error = EINVAL; /* Skip this inp. */ + } else if (ssk->socket) + error = cr_canseesocket(req->td->td_ucred, + ssk->socket); + else + error = EINVAL; + if (error) + goto next; + + bzero(&xt, sizeof(xt)); + xt.xt_len = sizeof xt; + xt.xt_inp.inp_gencnt = 0; + xt.xt_inp.inp_vflag = INP_IPV4; + memcpy(&xt.xt_inp.inp_laddr, &ssk->laddr, sizeof(ssk->laddr)); + xt.xt_inp.inp_lport = ssk->lport; + memcpy(&xt.xt_inp.inp_faddr, &ssk->faddr, sizeof(ssk->faddr)); + xt.xt_inp.inp_fport = ssk->fport; + xt.xt_tp.t_state = ssk->state; + if (ssk->socket != NULL) + sotoxsocket(ssk->socket, &xt.xt_socket); + else + bzero(&xt.xt_socket, sizeof xt.xt_socket); + xt.xt_socket.xso_protocol = IPPROTO_TCP; + SDP_RUNLOCK(ssk); + error = SYSCTL_OUT(req, &xt, sizeof xt); + i++; + continue; +next: + SDP_RUNLOCK(ssk); + } + if (!error) { + /* + * Give the user an updated idea of our state. + * If the generation differs from what we told + * her before, she knows that something happened + * while we were processing this request, and it + * might be necessary to retry. + */ + xig.xig_gen = 0; + xig.xig_sogen = so_gencnt; + xig.xig_count = sdp_count; + error = SYSCTL_OUT(req, &xig, sizeof xig); + } + SDP_LIST_RUNLOCK(); + return (error); +} + +SYSCTL_NODE(_net_inet, -1, sdp, CTLFLAG_RW, 0, "SDP"); + +SYSCTL_PROC(_net_inet_sdp, TCPCTL_PCBLIST, pcblist, CTLFLAG_RD, 0, 0, + sdp_pcblist, "S,xtcpcb", "List of active SDP connections"); + static void sdp_zone_change(void *tag) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101100356.p0A3uw5P066293>