tcp_usrreq.c (289276) | tcp_usrreq.c (292309) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. 4 * Copyright (c) 2006-2007 Robert N. M. Watson 5 * Copyright (c) 2010-2011 Juniper Networks, Inc. 6 * All rights reserved. 7 * 8 * Portions of this software were developed by Robert N. M. Watson under --- 22 unchanged lines hidden (view full) --- 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94 36 */ 37 38#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1988, 1993 3 * The Regents of the University of California. 4 * Copyright (c) 2006-2007 Robert N. M. Watson 5 * Copyright (c) 2010-2011 Juniper Networks, Inc. 6 * All rights reserved. 7 * 8 * Portions of this software were developed by Robert N. M. Watson under --- 22 unchanged lines hidden (view full) --- 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94 36 */ 37 38#include <sys/cdefs.h> |
39__FBSDID("$FreeBSD: head/sys/netinet/tcp_usrreq.c 289276 2015-10-14 00:35:37Z hiren $"); | 39__FBSDID("$FreeBSD: head/sys/netinet/tcp_usrreq.c 292309 2015-12-16 00:56:45Z rrs $"); |
40 41#include "opt_ddb.h" 42#include "opt_inet.h" 43#include "opt_inet6.h" 44#include "opt_tcpdebug.h" 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/limits.h> 49#include <sys/malloc.h> | 40 41#include "opt_ddb.h" 42#include "opt_inet.h" 43#include "opt_inet6.h" 44#include "opt_tcpdebug.h" 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/limits.h> 49#include <sys/malloc.h> |
50#include <sys/refcount.h> |
|
50#include <sys/kernel.h> 51#include <sys/sysctl.h> 52#include <sys/mbuf.h> 53#ifdef INET6 54#include <sys/domain.h> 55#endif /* INET6 */ 56#include <sys/socket.h> 57#include <sys/socketvar.h> --- 446 unchanged lines hidden (view full) --- 504 goto out; 505#ifdef TCP_OFFLOAD 506 if (registered_toedevs > 0 && 507 (so->so_options & SO_NO_OFFLOAD) == 0 && 508 (error = tcp_offload_connect(so, nam)) == 0) 509 goto out; 510#endif 511 tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); | 51#include <sys/kernel.h> 52#include <sys/sysctl.h> 53#include <sys/mbuf.h> 54#ifdef INET6 55#include <sys/domain.h> 56#endif /* INET6 */ 57#include <sys/socket.h> 58#include <sys/socketvar.h> --- 446 unchanged lines hidden (view full) --- 505 goto out; 506#ifdef TCP_OFFLOAD 507 if (registered_toedevs > 0 && 508 (so->so_options & SO_NO_OFFLOAD) == 0 && 509 (error = tcp_offload_connect(so, nam)) == 0) 510 goto out; 511#endif 512 tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); |
512 error = tcp_output(tp); | 513 error = tp->t_fb->tfb_tcp_output(tp); |
513out: 514 TCPDEBUG2(PRU_CONNECT); 515 INP_WUNLOCK(inp); 516 return (error); 517} 518#endif /* INET */ 519 520#ifdef INET6 --- 53 unchanged lines hidden (view full) --- 574 if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0) 575 goto out; 576#ifdef TCP_OFFLOAD 577 if (registered_toedevs > 0 && 578 (so->so_options & SO_NO_OFFLOAD) == 0 && 579 (error = tcp_offload_connect(so, nam)) == 0) 580 goto out; 581#endif | 514out: 515 TCPDEBUG2(PRU_CONNECT); 516 INP_WUNLOCK(inp); 517 return (error); 518} 519#endif /* INET */ 520 521#ifdef INET6 --- 53 unchanged lines hidden (view full) --- 575 if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0) 576 goto out; 577#ifdef TCP_OFFLOAD 578 if (registered_toedevs > 0 && 579 (so->so_options & SO_NO_OFFLOAD) == 0 && 580 (error = tcp_offload_connect(so, nam)) == 0) 581 goto out; 582#endif |
582 error = tcp_output(tp); | 583 error = tp->t_fb->tfb_tcp_output(tp); |
583 goto out; 584 } 585#endif 586 inp->inp_vflag &= ~INP_IPV4; 587 inp->inp_vflag |= INP_IPV6; 588 inp->inp_inc.inc_flags |= INC_ISIPV6; 589 if ((error = prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr)) != 0) 590 goto out; 591 if ((error = tcp6_connect(tp, nam, td)) != 0) 592 goto out; 593#ifdef TCP_OFFLOAD 594 if (registered_toedevs > 0 && 595 (so->so_options & SO_NO_OFFLOAD) == 0 && 596 (error = tcp_offload_connect(so, nam)) == 0) 597 goto out; 598#endif 599 tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); | 584 goto out; 585 } 586#endif 587 inp->inp_vflag &= ~INP_IPV4; 588 inp->inp_vflag |= INP_IPV6; 589 inp->inp_inc.inc_flags |= INC_ISIPV6; 590 if ((error = prison_remote_ip6(td->td_ucred, &sin6p->sin6_addr)) != 0) 591 goto out; 592 if ((error = tcp6_connect(tp, nam, td)) != 0) 593 goto out; 594#ifdef TCP_OFFLOAD 595 if (registered_toedevs > 0 && 596 (so->so_options & SO_NO_OFFLOAD) == 0 && 597 (error = tcp_offload_connect(so, nam)) == 0) 598 goto out; 599#endif 600 tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); |
600 error = tcp_output(tp); | 601 error = tp->t_fb->tfb_tcp_output(tp); |
601 602out: 603 TCPDEBUG2(PRU_CONNECT); 604 TCP_PROBE2(debug__user, tp, PRU_CONNECT); 605 INP_WUNLOCK(inp); 606 return (error); 607} 608#endif /* INET6 */ --- 159 unchanged lines hidden (view full) --- 768 error = ECONNRESET; 769 goto out; 770 } 771 tp = intotcpcb(inp); 772 TCPDEBUG1(); 773 socantsendmore(so); 774 tcp_usrclosed(tp); 775 if (!(inp->inp_flags & INP_DROPPED)) | 602 603out: 604 TCPDEBUG2(PRU_CONNECT); 605 TCP_PROBE2(debug__user, tp, PRU_CONNECT); 606 INP_WUNLOCK(inp); 607 return (error); 608} 609#endif /* INET6 */ --- 159 unchanged lines hidden (view full) --- 769 error = ECONNRESET; 770 goto out; 771 } 772 tp = intotcpcb(inp); 773 TCPDEBUG1(); 774 socantsendmore(so); 775 tcp_usrclosed(tp); 776 if (!(inp->inp_flags & INP_DROPPED)) |
776 error = tcp_output(tp); | 777 error = tp->t_fb->tfb_tcp_output(tp); |
777 778out: 779 TCPDEBUG2(PRU_SHUTDOWN); 780 TCP_PROBE2(debug__user, tp, PRU_SHUTDOWN); 781 INP_WUNLOCK(inp); 782 INP_INFO_RUNLOCK(&V_tcbinfo); 783 784 return (error); --- 19 unchanged lines hidden (view full) --- 804 } 805 tp = intotcpcb(inp); 806 TCPDEBUG1(); 807#ifdef TCP_OFFLOAD 808 if (tp->t_flags & TF_TOE) 809 tcp_offload_rcvd(tp); 810 else 811#endif | 778 779out: 780 TCPDEBUG2(PRU_SHUTDOWN); 781 TCP_PROBE2(debug__user, tp, PRU_SHUTDOWN); 782 INP_WUNLOCK(inp); 783 INP_INFO_RUNLOCK(&V_tcbinfo); 784 785 return (error); --- 19 unchanged lines hidden (view full) --- 805 } 806 tp = intotcpcb(inp); 807 TCPDEBUG1(); 808#ifdef TCP_OFFLOAD 809 if (tp->t_flags & TF_TOE) 810 tcp_offload_rcvd(tp); 811 else 812#endif |
812 tcp_output(tp); | 813 tp->t_fb->tfb_tcp_output(tp); |
813 814out: 815 TCPDEBUG2(PRU_RCVD); 816 TCP_PROBE2(debug__user, tp, PRU_RCVD); 817 INP_WUNLOCK(inp); 818 return (error); 819} 820 --- 85 unchanged lines hidden (view full) --- 906 INP_INFO_RLOCK_ASSERT(&V_tcbinfo); 907 socantsendmore(so); 908 tcp_usrclosed(tp); 909 } 910 if (!(inp->inp_flags & INP_DROPPED) && 911 !(flags & PRUS_NOTREADY)) { 912 if (flags & PRUS_MORETOCOME) 913 tp->t_flags |= TF_MORETOCOME; | 814 815out: 816 TCPDEBUG2(PRU_RCVD); 817 TCP_PROBE2(debug__user, tp, PRU_RCVD); 818 INP_WUNLOCK(inp); 819 return (error); 820} 821 --- 85 unchanged lines hidden (view full) --- 907 INP_INFO_RLOCK_ASSERT(&V_tcbinfo); 908 socantsendmore(so); 909 tcp_usrclosed(tp); 910 } 911 if (!(inp->inp_flags & INP_DROPPED) && 912 !(flags & PRUS_NOTREADY)) { 913 if (flags & PRUS_MORETOCOME) 914 tp->t_flags |= TF_MORETOCOME; |
914 error = tcp_output(tp); | 915 error = tp->t_fb->tfb_tcp_output(tp); |
915 if (flags & PRUS_MORETOCOME) 916 tp->t_flags &= ~TF_MORETOCOME; 917 } 918 } else { 919 /* 920 * XXXRW: PRUS_EOF not implemented with PRUS_OOB? 921 */ 922 SOCKBUF_LOCK(&so->so_snd); --- 33 unchanged lines hidden (view full) --- 956 if (error) 957 goto out; 958 tp->snd_wnd = TTCP_CLIENT_SND_WND; 959 tcp_mss(tp, -1); 960 } 961 tp->snd_up = tp->snd_una + sbavail(&so->so_snd); 962 if (!(flags & PRUS_NOTREADY)) { 963 tp->t_flags |= TF_FORCEDATA; | 916 if (flags & PRUS_MORETOCOME) 917 tp->t_flags &= ~TF_MORETOCOME; 918 } 919 } else { 920 /* 921 * XXXRW: PRUS_EOF not implemented with PRUS_OOB? 922 */ 923 SOCKBUF_LOCK(&so->so_snd); --- 33 unchanged lines hidden (view full) --- 957 if (error) 958 goto out; 959 tp->snd_wnd = TTCP_CLIENT_SND_WND; 960 tcp_mss(tp, -1); 961 } 962 tp->snd_up = tp->snd_una + sbavail(&so->so_snd); 963 if (!(flags & PRUS_NOTREADY)) { 964 tp->t_flags |= TF_FORCEDATA; |
964 error = tcp_output(tp); | 965 error = tp->t_fb->tfb_tcp_output(tp); |
965 tp->t_flags &= ~TF_FORCEDATA; 966 } 967 } 968out: 969 TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB : 970 ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); 971 TCP_PROBE2(debug__user, tp, (flags & PRUS_OOB) ? PRU_SENDOOB : 972 ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); --- 19 unchanged lines hidden (view full) --- 992 return (ECONNRESET); 993 } 994 tp = intotcpcb(inp); 995 996 SOCKBUF_LOCK(&so->so_snd); 997 error = sbready(&so->so_snd, m, count); 998 SOCKBUF_UNLOCK(&so->so_snd); 999 if (error == 0) | 966 tp->t_flags &= ~TF_FORCEDATA; 967 } 968 } 969out: 970 TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB : 971 ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); 972 TCP_PROBE2(debug__user, tp, (flags & PRUS_OOB) ? PRU_SENDOOB : 973 ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); --- 19 unchanged lines hidden (view full) --- 993 return (ECONNRESET); 994 } 995 tp = intotcpcb(inp); 996 997 SOCKBUF_LOCK(&so->so_snd); 998 error = sbready(&so->so_snd, m, count); 999 SOCKBUF_UNLOCK(&so->so_snd); 1000 if (error == 0) |
1000 error = tcp_output(tp); | 1001 error = tp->t_fb->tfb_tcp_output(tp); |
1001 INP_WUNLOCK(inp); 1002 1003 return (error); 1004} 1005 1006/* 1007 * Abort the TCP. Drop the connection abruptly. 1008 */ --- 335 unchanged lines hidden (view full) --- 1344 return (ECONNRESET); \ 1345 } \ 1346 tp = intotcpcb(inp); \ 1347} while(0) 1348 1349int 1350tcp_ctloutput(struct socket *so, struct sockopt *sopt) 1351{ | 1002 INP_WUNLOCK(inp); 1003 1004 return (error); 1005} 1006 1007/* 1008 * Abort the TCP. Drop the connection abruptly. 1009 */ --- 335 unchanged lines hidden (view full) --- 1345 return (ECONNRESET); \ 1346 } \ 1347 tp = intotcpcb(inp); \ 1348} while(0) 1349 1350int 1351tcp_ctloutput(struct socket *so, struct sockopt *sopt) 1352{ |
1352 int error, opt, optval; 1353 u_int ui; | 1353 int error; |
1354 struct inpcb *inp; 1355 struct tcpcb *tp; | 1354 struct inpcb *inp; 1355 struct tcpcb *tp; |
1356 struct tcp_info ti; 1357 char buf[TCP_CA_NAME_MAX]; 1358 struct cc_algo *algo; | 1356 struct tcp_function_block *blk; 1357 struct tcp_function_set fsn; |
1359 1360 error = 0; 1361 inp = sotoinpcb(so); 1362 KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL")); 1363 INP_WLOCK(inp); 1364 if (sopt->sopt_level != IPPROTO_TCP) { 1365#ifdef INET6 1366 if (inp->inp_vflag & INP_IPV6PROTO) { --- 11 unchanged lines hidden (view full) --- 1378 } 1379#endif 1380 return (error); 1381 } 1382 if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { 1383 INP_WUNLOCK(inp); 1384 return (ECONNRESET); 1385 } | 1358 1359 error = 0; 1360 inp = sotoinpcb(so); 1361 KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL")); 1362 INP_WLOCK(inp); 1363 if (sopt->sopt_level != IPPROTO_TCP) { 1364#ifdef INET6 1365 if (inp->inp_vflag & INP_IPV6PROTO) { --- 11 unchanged lines hidden (view full) --- 1377 } 1378#endif 1379 return (error); 1380 } 1381 if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { 1382 INP_WUNLOCK(inp); 1383 return (ECONNRESET); 1384 } |
1385 tp = intotcpcb(inp); 1386 /* 1387 * Protect the TCP option TCP_FUNCTION_BLK so 1388 * that a sub-function can *never* overwrite this. 1389 */ 1390 if ((sopt->sopt_dir == SOPT_SET) && 1391 (sopt->sopt_name == TCP_FUNCTION_BLK)) { 1392 INP_WUNLOCK(inp); 1393 error = sooptcopyin(sopt, &fsn, sizeof fsn, 1394 sizeof fsn); 1395 if (error) 1396 return (error); 1397 INP_WLOCK_RECHECK(inp); 1398 if (tp->t_state != TCPS_CLOSED) { 1399 /* 1400 * The user has advanced the state 1401 * past the initial point, we can't 1402 * switch since we are down the road 1403 * and a new set of functions may 1404 * not be compatibile. 1405 */ 1406 INP_WUNLOCK(inp); 1407 return(EINVAL); 1408 } 1409 blk = find_and_ref_tcp_functions(&fsn); 1410 if (blk == NULL) { 1411 INP_WUNLOCK(inp); 1412 return (ENOENT); 1413 } 1414 if (tp->t_fb != blk) { 1415 if (blk->tfb_flags & TCP_FUNC_BEING_REMOVED) { 1416 refcount_release(&blk->tfb_refcnt); 1417 INP_WUNLOCK(inp); 1418 return (ENOENT); 1419 } 1420 /* 1421 * Release the old refcnt, the 1422 * lookup acquires a ref on the 1423 * new one. 1424 */ 1425 if (tp->t_fb->tfb_tcp_fb_fini) 1426 (*tp->t_fb->tfb_tcp_fb_fini)(tp); 1427 refcount_release(&tp->t_fb->tfb_refcnt); 1428 tp->t_fb = blk; 1429 if (tp->t_fb->tfb_tcp_fb_init) { 1430 (*tp->t_fb->tfb_tcp_fb_init)(tp); 1431 } 1432 } 1433#ifdef TCP_OFFLOAD 1434 if (tp->t_flags & TF_TOE) { 1435 tcp_offload_ctloutput(tp, sopt->sopt_dir, 1436 sopt->sopt_name); 1437 } 1438#endif 1439 INP_WUNLOCK(inp); 1440 return (error); 1441 } else if ((sopt->sopt_dir == SOPT_GET) && 1442 (sopt->sopt_name == TCP_FUNCTION_BLK)) { 1443 strcpy(fsn.function_set_name, tp->t_fb->tfb_tcp_block_name); 1444 fsn.pcbcnt = tp->t_fb->tfb_refcnt; 1445 INP_WUNLOCK(inp); 1446 error = sooptcopyout(sopt, &fsn, sizeof fsn); 1447 return (error); 1448 } 1449 /* Pass in the INP locked, called must unlock it */ 1450 return (tp->t_fb->tfb_tcp_ctloutput(so, sopt, inp, tp)); 1451} |
|
1386 | 1452 |
1453int 1454tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp, struct tcpcb *tp) 1455{ 1456 int error, opt, optval; 1457 u_int ui; 1458 struct tcp_info ti; 1459 struct cc_algo *algo; 1460 char buf[TCP_CA_NAME_MAX]; 1461 |
|
1387 switch (sopt->sopt_dir) { 1388 case SOPT_SET: 1389 switch (sopt->sopt_name) { 1390#ifdef TCP_SIGNATURE 1391 case TCP_MD5SIG: 1392 INP_WUNLOCK(inp); 1393 error = sooptcopyin(sopt, &optval, sizeof optval, 1394 sizeof optval); --- 51 unchanged lines hidden (view full) --- 1446 return (error); 1447 1448 INP_WLOCK_RECHECK(inp); 1449 if (optval) 1450 tp->t_flags |= TF_NOPUSH; 1451 else if (tp->t_flags & TF_NOPUSH) { 1452 tp->t_flags &= ~TF_NOPUSH; 1453 if (TCPS_HAVEESTABLISHED(tp->t_state)) | 1462 switch (sopt->sopt_dir) { 1463 case SOPT_SET: 1464 switch (sopt->sopt_name) { 1465#ifdef TCP_SIGNATURE 1466 case TCP_MD5SIG: 1467 INP_WUNLOCK(inp); 1468 error = sooptcopyin(sopt, &optval, sizeof optval, 1469 sizeof optval); --- 51 unchanged lines hidden (view full) --- 1521 return (error); 1522 1523 INP_WLOCK_RECHECK(inp); 1524 if (optval) 1525 tp->t_flags |= TF_NOPUSH; 1526 else if (tp->t_flags & TF_NOPUSH) { 1527 tp->t_flags &= ~TF_NOPUSH; 1528 if (TCPS_HAVEESTABLISHED(tp->t_state)) |
1454 error = tcp_output(tp); | 1529 error = tp->t_fb->tfb_tcp_output(tp); |
1455 } 1456 goto unlock_and_done; 1457 1458 case TCP_MAXSEG: 1459 INP_WUNLOCK(inp); 1460 error = sooptcopyin(sopt, &optval, sizeof optval, 1461 sizeof optval); 1462 if (error) --- 302 unchanged lines hidden (view full) --- 1765 tp = tcp_drop(tp, 0); 1766 KASSERT(tp != NULL, 1767 ("tcp_disconnect: tcp_drop() returned NULL")); 1768 } else { 1769 soisdisconnecting(so); 1770 sbflush(&so->so_rcv); 1771 tcp_usrclosed(tp); 1772 if (!(inp->inp_flags & INP_DROPPED)) | 1530 } 1531 goto unlock_and_done; 1532 1533 case TCP_MAXSEG: 1534 INP_WUNLOCK(inp); 1535 error = sooptcopyin(sopt, &optval, sizeof optval, 1536 sizeof optval); 1537 if (error) --- 302 unchanged lines hidden (view full) --- 1840 tp = tcp_drop(tp, 0); 1841 KASSERT(tp != NULL, 1842 ("tcp_disconnect: tcp_drop() returned NULL")); 1843 } else { 1844 soisdisconnecting(so); 1845 sbflush(&so->so_rcv); 1846 tcp_usrclosed(tp); 1847 if (!(inp->inp_flags & INP_DROPPED)) |
1773 tcp_output(tp); | 1848 tp->t_fb->tfb_tcp_output(tp); |
1774 } 1775} 1776 1777/* 1778 * User issued close, and wish to trail through shutdown states: 1779 * if never received SYN, just forget it. If got a SYN from peer, 1780 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 1781 * If already got a FIN from peer, then almost done; go to LAST_ACK --- 366 unchanged lines hidden --- | 1849 } 1850} 1851 1852/* 1853 * User issued close, and wish to trail through shutdown states: 1854 * if never received SYN, just forget it. If got a SYN from peer, 1855 * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. 1856 * If already got a FIN from peer, then almost done; go to LAST_ACK --- 366 unchanged lines hidden --- |