Page MenuHomeFreeBSD

D45411.id139254.diff
No OneTemporary

D45411.id139254.diff

diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -437,7 +437,7 @@
}
struct tcp_function_block *
-find_and_ref_tcp_fb(struct tcp_function_block *blk)
+tcp_find_and_ref_fb(struct tcp_function_block *blk)
{
struct tcp_function_block *rblk;
@@ -480,8 +480,8 @@
return (found);
}
-static struct tcp_function_block *
-find_and_ref_tcp_default_fb(void)
+struct tcp_function_block *
+tcp_find_and_ref_default_fb(void)
{
struct tcp_function_block *rblk;
@@ -510,7 +510,7 @@
* default, unless this stack is the user-selected
* default.
*/
- tfb = find_and_ref_tcp_default_fb();
+ tfb = tcp_find_and_ref_default_fb();
if (tfb == tp->t_fb) {
refcount_release(&tfb->tfb_refcnt);
tfb = NULL;
@@ -546,7 +546,7 @@
* If that wasn't feasible, use the built-in default
* stack which is not allowed to reject anyone.
*/
- tfb = find_and_ref_tcp_fb(&tcp_def_funcblk);
+ tfb = tcp_find_and_ref_fb(&tcp_def_funcblk);
if (tfb == NULL) {
/* there always should be a default */
panic("Can't refer to tcp_def_funcblk");
@@ -2178,9 +2178,11 @@
* Create a new TCP control block, making an empty reassembly queue and hooking
* it to the argument protocol control block. The `inp' parameter must have
* come from the zone allocator set up by tcpcbstor declaration.
+ * The caller needs to provide a pointer to a TCP function block, for which
+ * it holds a reference count.
*/
struct tcpcb *
-tcp_newtcpcb(struct inpcb *inp)
+tcp_newtcpcb(struct inpcb *inp, struct tcp_function_block *tfb)
{
struct tcpcb *tp = intotcpcb(inp);
#ifdef INET6
@@ -2197,10 +2199,7 @@
/* Initialise cc_var struct for this tcpcb. */
tp->t_ccv.type = IPPROTO_TCP;
tp->t_ccv.ccvc.tcp = tp;
- rw_rlock(&tcp_function_lock);
- tp->t_fb = V_tcp_func_set_ptr;
- refcount_acquire(&tp->t_fb->tfb_refcnt);
- rw_runlock(&tcp_function_lock);
+ tp->t_fb = tfb;
/*
* Use the current system default CC algorithm.
*/
@@ -2209,17 +2208,11 @@
if (CC_ALGO(tp)->cb_init != NULL)
if (CC_ALGO(tp)->cb_init(&tp->t_ccv, NULL) > 0) {
cc_detach(tp);
- if (tp->t_fb->tfb_tcp_fb_fini)
- (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
- refcount_release(&tp->t_fb->tfb_refcnt);
return (NULL);
}
#ifdef TCP_HHOOK
if (khelp_init_osd(HELPER_CLASS_TCP, &tp->t_osd)) {
- if (tp->t_fb->tfb_tcp_fb_fini)
- (*tp->t_fb->tfb_tcp_fb_fini)(tp, 1);
- refcount_release(&tp->t_fb->tfb_refcnt);
return (NULL);
}
#endif
@@ -2293,7 +2286,6 @@
tp->t_pacing_rate = -1;
if (tp->t_fb->tfb_tcp_fb_init) {
if ((*tp->t_fb->tfb_tcp_fb_init)(tp, &tp->t_fb_ptr)) {
- refcount_release(&tp->t_fb->tfb_refcnt);
return (NULL);
}
}
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -777,7 +777,7 @@
static struct socket *
syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
{
- struct tcp_function_block *blk;
+ struct tcp_function_block *tfb;
struct inpcb *inp = NULL;
struct socket *so;
struct tcpcb *tp;
@@ -802,7 +802,13 @@
goto allocfail;
}
inp = sotoinpcb(so);
- if ((tp = tcp_newtcpcb(inp)) == NULL) {
+ if (V_functions_inherit_listen_socket_stack)
+ tfb = tcp_find_and_ref_fb(sototcpcb(lso)->t_fb);
+ else
+ tfb = tcp_find_and_ref_default_fb();
+ KASSERT(tfb != NULL, ("Cannot find TCP function block."));
+ if ((tp = tcp_newtcpcb(inp, tfb)) == NULL) {
+ refcount_release(&tfb->tfb_refcnt);
in_pcbfree(inp);
sodealloc(so);
goto allocfail;
@@ -912,37 +918,6 @@
tp->t_port = sc->sc_port;
tcp_rcvseqinit(tp);
tcp_sendseqinit(tp);
- blk = sototcpcb(lso)->t_fb;
- if (V_functions_inherit_listen_socket_stack && blk != tp->t_fb) {
- /*
- * Our parents t_fb was not the default,
- * we need to release our ref on tp->t_fb and
- * pickup one on the new entry.
- */
- struct tcp_function_block *rblk;
- void *ptr = NULL;
-
- rblk = find_and_ref_tcp_fb(blk);
- KASSERT(rblk != NULL,
- ("cannot find blk %p out of syncache?", blk));
-
- if (rblk->tfb_tcp_fb_init == NULL ||
- (*rblk->tfb_tcp_fb_init)(tp, &ptr) == 0) {
- /* Release the old stack */
- if (tp->t_fb->tfb_tcp_fb_fini != NULL)
- (*tp->t_fb->tfb_tcp_fb_fini)(tp, 0);
- refcount_release(&tp->t_fb->tfb_refcnt);
- /* Now set in all the pointers */
- tp->t_fb = rblk;
- tp->t_fb_ptr = ptr;
- } else {
- /*
- * Initialization failed. Release the reference count on
- * the looked up default stack.
- */
- refcount_release(&rblk->tfb_refcnt);
- }
- }
tp->snd_wl1 = sc->sc_irs;
tp->snd_max = tp->iss + 1;
tp->snd_nxt = tp->iss + 1;
@@ -1053,6 +1028,7 @@
return (NULL);
abort:
+ refcount_release(&tfb->tfb_refcnt);
in_pcbfree(inp);
sodealloc(so);
if ((s = tcp_log_addrs(&sc->sc_inc, NULL, NULL, NULL))) {
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -156,6 +156,7 @@
tcp_usr_attach(struct socket *so, int proto, struct thread *td)
{
struct inpcb *inp;
+ struct tcp_function_block *tfb;
struct tcpcb *tp = NULL;
int error;
@@ -172,9 +173,11 @@
if (error)
goto out;
inp = sotoinpcb(so);
- tp = tcp_newtcpcb(inp);
+ tfb = tcp_find_and_ref_default_fb();
+ tp = tcp_newtcpcb(inp, tfb);
if (tp == NULL) {
error = ENOBUFS;
+ refcount_release(&tfb->tfb_refcnt);
in_pcbfree(inp);
goto out;
}
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1403,8 +1403,8 @@
int find_tcp_function_alias(struct tcp_function_block *blk, struct tcp_function_set *fs);
uint32_t tcp_get_srtt(struct tcpcb *tp, int granularity);
void tcp_switch_back_to_default(struct tcpcb *tp);
-struct tcp_function_block *
-find_and_ref_tcp_fb(struct tcp_function_block *fs);
+struct tcp_function_block *tcp_find_and_ref_fb(struct tcp_function_block *fs);
+struct tcp_function_block *tcp_find_and_ref_default_fb(void);
int tcp_default_ctloutput(struct tcpcb *tp, struct sockopt *sopt);
int tcp_ctloutput_set(struct inpcb *inp, struct sockopt *sopt);
void tcp_log_socket_option(struct tcpcb *tp, uint32_t option_num,
@@ -1445,7 +1445,7 @@
void tcp_mss(struct tcpcb *, int);
int tcp_mssopt(struct in_conninfo *);
struct tcpcb *
- tcp_newtcpcb(struct inpcb *);
+ tcp_newtcpcb(struct inpcb *, struct tcp_function_block *);
int tcp_default_output(struct tcpcb *);
void tcp_state_change(struct tcpcb *, int);
void tcp_respond(struct tcpcb *, void *,

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 25, 1:54 AM (22 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27920590
Default Alt Text
D45411.id139254.diff (6 KB)

Event Timeline