39#include "opt_tcpdebug.h"
40#include "opt_ratelimit.h"
43#include <sys/module.h>
44#include <sys/kernel.h>
45#include <sys/libkern.h>
49#include <sys/malloc.h>
52#include <sys/socket.h>
53#include <sys/socketvar.h>
54#include <sys/sysctl.h>
61#include <sys/refcount.h>
63#include <sys/eventhandler.h>
65#include <sys/kthread.h>
68#include <sys/tim_filter.h>
70#include <sys/protosw.h>
72#include <sys/kern_prefetch.h>
75#include <net/route/nhop.h>
88#include <netinet6/in6_pcb.h>
89#include <netinet6/ip6_var.h>
109#include <netinet6/tcp6_var.h>
113#include <netipsec/ipsec_support.h>
115#include <net/if_var.h>
116#include <net/ethernet.h>
118#if defined(IPSEC) || defined(IPSEC_SUPPORT)
119#include <netipsec/ipsec.h>
120#include <netipsec/ipsec6.h>
125#include <machine/in_cksum.h>
128#include <security/mac/mac_framework.h>
140#define TCPT_RANGESET_NOSLOP(tv, value, tvmin, tvmax) do { \
142 if ((u_long)(tv) < (u_long)(tvmin)) \
144 if ((u_long)(tv) > (u_long)(tvmax)) \
293#define BBR_HPTSI_GAIN_MAX 8
425#define BBR_MAX_STAT 19
445 uint32_t useconds_time, uint64_t bw);
459 int32_t pkt_epoch,
uint32_t losses);
570 uint32_t thresh, exp, to, srtt, time_since_sent, tstmp_touse;
572 int32_t is_tlp_timer = 0;
601 time_since_sent = cts - tstmp_touse;
607 tov = ((uint64_t)(TICKS_2_USEC(tp->
t_srtt) +
611 if (tov > time_since_sent)
612 tov -= time_since_sent;
678 time_since_sent = cts - tstmp_touse;
682 if (thresh > time_since_sent)
683 to = thresh - time_since_sent;
711 if (is_tlp_timer == 0) {
745 int32_t delay_calc = 0;
775 if (delay_calc <= slot)
818 ((hpts_timeout == 0) ||
833 if ((hpts_timeout == 0) &&
860 if (left < hpts_timeout)
881 hpts_timeout += slot;
888 if (hpts_timeout > 0x7ffffffe)
889 hpts_timeout = 0x7ffffffe;
896 (slot <= hpts_timeout)) ) {
920 }
else if (hpts_timeout) {
990 }
else if (sbavail(&inp->
inp_socket->so_snd) &&
999 inp->
inp_socket->so_options & SO_KEEPALIVE) &&
1076 if (hpts_timeout == 0) {
1086 if (hpts_timeout > 0x7ffffffe)
1087 hpts_timeout = 0x7ffffffe;
1115 return (cts - earlier_time);
1122 if (
TSTMP_GEQ((cts + 10000), earlier_time))
1128 return (cts - earlier_time);
1138 if (error || req->newptr == NULL)
1141 error = SYSCTL_IN(req, &stat,
sizeof(
uint32_t));
1145#ifdef BBR_INVARIANTS
1146 printf(
"Clearing BBR lost counters\n");
1151 }
else if (stat == 2) {
1152#ifdef BBR_INVARIANTS
1153 printf(
"Clearing BBR option counters\n");
1156 }
else if (stat == 3) {
1157#ifdef BBR_INVARIANTS
1158 printf(
"Clearing BBR stats counters\n");
1161 }
else if (stat == 4) {
1162#ifdef BBR_INVARIANTS
1163 printf(
"Clearing BBR out-size counters\n");
1174 struct sysctl_oid *bbr_probertt;
1175 struct sysctl_oid *bbr_hptsi;
1176 struct sysctl_oid *bbr_measure;
1177 struct sysctl_oid *bbr_cwnd;
1178 struct sysctl_oid *bbr_timeout;
1179 struct sysctl_oid *bbr_states;
1180 struct sysctl_oid *bbr_startup;
1181 struct sysctl_oid *bbr_policer;
1188 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
1191 SYSCTL_CHILDREN(bbr_probertt),
1192 OID_AUTO,
"gain", CTLFLAG_RW,
1194 "What is the filter gain drop in probe_rtt (0=disable)?");
1196 SYSCTL_CHILDREN(bbr_probertt),
1197 OID_AUTO,
"cwnd", CTLFLAG_RW,
1199 "How many mss's are outstanding during probe-rtt");
1201 SYSCTL_CHILDREN(bbr_probertt),
1202 OID_AUTO,
"int", CTLFLAG_RW,
1204 "If RTT has not shrank in this many micro-seconds enter probe-rtt");
1206 SYSCTL_CHILDREN(bbr_probertt),
1207 OID_AUTO,
"mintime", CTLFLAG_RW,
1209 "How many microseconds in probe-rtt");
1211 SYSCTL_CHILDREN(bbr_probertt),
1212 OID_AUTO,
"filter_len_sec", CTLFLAG_RW,
1214 "How long in seconds does the rttProp filter run?");
1216 SYSCTL_CHILDREN(bbr_probertt),
1217 OID_AUTO,
"drain_rtt", CTLFLAG_RW,
1219 "What is the drain rtt to use in probeRTT (rtt_prop=0, rtt_rack=1, rtt_pkt=2, rtt_srtt=3?");
1221 SYSCTL_CHILDREN(bbr_probertt),
1222 OID_AUTO,
"can_force", CTLFLAG_RW,
1224 "If we keep setting new low rtt's but delay going in probe-rtt can we force in??");
1226 SYSCTL_CHILDREN(bbr_probertt),
1227 OID_AUTO,
"enter_sets_force", CTLFLAG_RW,
1229 "In NF mode, do we imitate google_mode and set the rttProp on entry to probe-rtt?");
1231 SYSCTL_CHILDREN(bbr_probertt),
1232 OID_AUTO,
"can_adjust", CTLFLAG_RW,
1234 "Can we dynamically adjust the probe-rtt limits and times?");
1236 SYSCTL_CHILDREN(bbr_probertt),
1237 OID_AUTO,
"is_ratio", CTLFLAG_RW,
1239 "is the limit to filter a ratio?");
1241 SYSCTL_CHILDREN(bbr_probertt),
1242 OID_AUTO,
"use_cwnd", CTLFLAG_RW,
1244 "Should we set/recover cwnd?");
1246 SYSCTL_CHILDREN(bbr_probertt),
1247 OID_AUTO,
"can_use_ts", CTLFLAG_RW,
1249 "Can we use the ms timestamp if available for retransmistted rtt calculations?");
1256 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
1259 SYSCTL_CHILDREN(bbr_hptsi),
1260 OID_AUTO,
"hw_pacing", CTLFLAG_RW,
1262 "Do we allow hardware pacing?");
1264 SYSCTL_CHILDREN(bbr_hptsi),
1265 OID_AUTO,
"hw_pacing_limit", CTLFLAG_RW,
1267 "Do we have a limited number of connections for pacing chelsio (0=no limit)?");
1269 SYSCTL_CHILDREN(bbr_hptsi),
1270 OID_AUTO,
"hw_pacing_adj", CTLFLAG_RW,
1272 "Multiplier to calculated tso size?");
1274 SYSCTL_CHILDREN(bbr_hptsi),
1275 OID_AUTO,
"hw_pacing_floor", CTLFLAG_RW,
1277 "Do we invoke the hardware pacing floor?");
1279 SYSCTL_CHILDREN(bbr_hptsi),
1280 OID_AUTO,
"hw_pacing_delay_cnt", CTLFLAG_RW,
1282 "How many packets must be sent after hdwr pacing is enabled");
1284 SYSCTL_CHILDREN(bbr_hptsi),
1285 OID_AUTO,
"bw_cross", CTLFLAG_RW,
1287 "What is the point where we cross over to linux like TSO size set");
1289 SYSCTL_CHILDREN(bbr_hptsi),
1290 OID_AUTO,
"seg_deltarg", CTLFLAG_RW,
1292 "What is the worse case delay target for hptsi < 48Mbp connections");
1294 SYSCTL_CHILDREN(bbr_hptsi),
1295 OID_AUTO,
"enet_oh", CTLFLAG_RW,
1297 "Do we include the ethernet overhead in calculating pacing delay?");
1299 SYSCTL_CHILDREN(bbr_hptsi),
1300 OID_AUTO,
"ip_oh", CTLFLAG_RW,
1302 "Do we include the IP overhead in calculating pacing delay?");
1304 SYSCTL_CHILDREN(bbr_hptsi),
1305 OID_AUTO,
"tcp_oh", CTLFLAG_RW,
1307 "Do we include the TCP overhead in calculating pacing delay?");
1309 SYSCTL_CHILDREN(bbr_hptsi),
1310 OID_AUTO,
"google_discount", CTLFLAG_RW,
1312 "What is the default google discount percentage wise for pacing (11 = 1.1%%)?");
1314 SYSCTL_CHILDREN(bbr_hptsi),
1315 OID_AUTO,
"all_get_min", CTLFLAG_RW,
1317 "If you are less than a MSS do you just get the min?");
1319 SYSCTL_CHILDREN(bbr_hptsi),
1320 OID_AUTO,
"tso_min", CTLFLAG_RW,
1322 "For 0 -> 24Mbps what is floor number of segments for TSO");
1324 SYSCTL_CHILDREN(bbr_hptsi),
1325 OID_AUTO,
"seg_tso_max", CTLFLAG_RW,
1327 "For 0 -> 24Mbps what is top number of segments for TSO");
1329 SYSCTL_CHILDREN(bbr_hptsi),
1330 OID_AUTO,
"seg_floor", CTLFLAG_RW,
1332 "Minimum TSO size we will fall too in segments");
1334 SYSCTL_CHILDREN(bbr_hptsi),
1335 OID_AUTO,
"utter_max", CTLFLAG_RW,
1337 "The absolute maximum that any pacing (outside of hardware) can be");
1339 SYSCTL_CHILDREN(bbr_hptsi),
1340 OID_AUTO,
"seg_divisor", CTLFLAG_RW,
1342 "What is the divisor in our hptsi TSO calculation 512Mbps < X > 24Mbps ");
1344 SYSCTL_CHILDREN(bbr_hptsi),
1345 OID_AUTO,
"srtt_mul", CTLFLAG_RW,
1347 "The multiplier for pace len max");
1349 SYSCTL_CHILDREN(bbr_hptsi),
1350 OID_AUTO,
"srtt_div", CTLFLAG_RW,
1352 "The divisor for pace len max");
1358 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
1359 "Measurement controls");
1361 SYSCTL_CHILDREN(bbr_measure),
1362 OID_AUTO,
"min_i_bw", CTLFLAG_RW,
1364 "Minimum initial b/w in bytes per second");
1366 SYSCTL_CHILDREN(bbr_measure),
1367 OID_AUTO,
"no_sack_needed", CTLFLAG_RW,
1369 "Do we allow bbr to run on connections not supporting SACK?");
1371 SYSCTL_CHILDREN(bbr_measure),
1372 OID_AUTO,
"use_google", CTLFLAG_RW,
1374 "Use has close to google V1.0 has possible?");
1376 SYSCTL_CHILDREN(bbr_measure),
1377 OID_AUTO,
"ts_limiting", CTLFLAG_RW,
1379 "Do we attempt to use the peers timestamp to limit b/w caculations?");
1381 SYSCTL_CHILDREN(bbr_measure),
1382 OID_AUTO,
"ts_can_raise", CTLFLAG_RW,
1384 "Can we raise the b/w via timestamp b/w calculation?");
1386 SYSCTL_CHILDREN(bbr_measure),
1387 OID_AUTO,
"ts_delta", CTLFLAG_RW,
1389 "How long in usec between ts of our sends in ts validation code?");
1391 SYSCTL_CHILDREN(bbr_measure),
1392 OID_AUTO,
"ts_peer_delta", CTLFLAG_RW,
1394 "What min numerical value should be between the peer deltas?");
1396 SYSCTL_CHILDREN(bbr_measure),
1397 OID_AUTO,
"ts_delta_percent", CTLFLAG_RW,
1399 "What percentage (150 = 15.0) do we allow variance for?");
1401 SYSCTL_CHILDREN(bbr_measure),
1402 OID_AUTO,
"min_measure_good_bw", CTLFLAG_RW,
1404 "What is the minimum measurement count we need before we switch to our b/w estimate");
1406 SYSCTL_CHILDREN(bbr_measure),
1407 OID_AUTO,
"min_measure_before_pace", CTLFLAG_RW,
1409 "How many pkt-epoch's (0 is off) do we need before pacing is on?");
1411 SYSCTL_CHILDREN(bbr_measure),
1412 OID_AUTO,
"quanta", CTLFLAG_RW,
1414 "Extra quanta to add when calculating the target (ID section 4.2.3.2).");
1416 SYSCTL_CHILDREN(bbr_measure),
1417 OID_AUTO,
"noretran", CTLFLAG_RW,
1419 "Should google mode not use retransmission measurements for the b/w estimation?");
1425 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
1428 SYSCTL_CHILDREN(bbr_states),
1429 OID_AUTO,
"idle_restart", CTLFLAG_RW,
1431 "Do we use a new special idle_restart state to ramp back up quickly?");
1433 SYSCTL_CHILDREN(bbr_states),
1434 OID_AUTO,
"idle_restart_threshold", CTLFLAG_RW,
1436 "How long must we be idle before we restart??");
1438 SYSCTL_CHILDREN(bbr_states),
1439 OID_AUTO,
"use_pkt_epoch", CTLFLAG_RW,
1441 "Do we use a pkt-epoch for substate if 0 rttProp?");
1443 SYSCTL_CHILDREN(bbr_states),
1444 OID_AUTO,
"startup_rtt_gain", CTLFLAG_RW,
1446 "What increase in RTT triggers us to stop ignoring no-loss and possibly exit startup?");
1448 SYSCTL_CHILDREN(bbr_states),
1449 OID_AUTO,
"drain_floor", CTLFLAG_RW,
1451 "What is the lowest we can drain (pg) too?");
1453 SYSCTL_CHILDREN(bbr_states),
1454 OID_AUTO,
"drain_2_target", CTLFLAG_RW,
1456 "Do we drain to target in drain substate?");
1458 SYSCTL_CHILDREN(bbr_states),
1459 OID_AUTO,
"gain_2_target", CTLFLAG_RW,
1461 "Does probe bw gain to target??");
1463 SYSCTL_CHILDREN(bbr_states),
1464 OID_AUTO,
"gain_extra_time", CTLFLAG_RW,
1466 "Does probe bw gain get the extra time too?");
1468 SYSCTL_CHILDREN(bbr_states),
1469 OID_AUTO,
"ld_div", CTLFLAG_RW,
1471 "Long drain drop divider?");
1473 SYSCTL_CHILDREN(bbr_states),
1474 OID_AUTO,
"ld_mul", CTLFLAG_RW,
1476 "Long drain drop multiplier?");
1478 SYSCTL_CHILDREN(bbr_states),
1479 OID_AUTO,
"rand_ot_disc", CTLFLAG_RW,
1481 "Random discount of the ot?");
1483 SYSCTL_CHILDREN(bbr_states),
1484 OID_AUTO,
"dr_filter_life", CTLFLAG_RW,
1486 "How many packet-epochs does the b/w delivery rate last?");
1488 SYSCTL_CHILDREN(bbr_states),
1489 OID_AUTO,
"subdrain_applimited", CTLFLAG_RW,
1491 "Does our sub-state drain invoke app limited if its long?");
1493 SYSCTL_CHILDREN(bbr_states),
1494 OID_AUTO,
"use_cwnd_subdrain", CTLFLAG_RW,
1496 "Should we set/recover cwnd for sub-state drain?");
1498 SYSCTL_CHILDREN(bbr_states),
1499 OID_AUTO,
"use_cwnd_maindrain", CTLFLAG_RW,
1501 "Should we set/recover cwnd for main-state drain?");
1503 SYSCTL_CHILDREN(bbr_states),
1504 OID_AUTO,
"google_gets_earlyout", CTLFLAG_RW,
1506 "Should we allow google probe-bw/drain to exit early at flight target?");
1508 SYSCTL_CHILDREN(bbr_states),
1509 OID_AUTO,
"google_exit_loss", CTLFLAG_RW,
1511 "Should we have losses exit gain of probebw in google mode??");
1517 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
1518 "Startup controls");
1520 SYSCTL_CHILDREN(bbr_startup),
1521 OID_AUTO,
"cheat_iwnd", CTLFLAG_RW,
1523 "Do we not pace but burst out initial windows has our TSO size?");
1525 SYSCTL_CHILDREN(bbr_startup),
1526 OID_AUTO,
"loss_threshold", CTLFLAG_RW,
1528 "In startup what is the loss threshold in a pe that will exit us from startup?");
1530 SYSCTL_CHILDREN(bbr_startup),
1531 OID_AUTO,
"use_lowerpg", CTLFLAG_RW,
1533 "Should we use a lower hptsi gain if we see loss in startup?");
1535 SYSCTL_CHILDREN(bbr_startup),
1536 OID_AUTO,
"gain", CTLFLAG_RW,
1538 "What gain percent do we need to see to stay in startup??");
1540 SYSCTL_CHILDREN(bbr_startup),
1541 OID_AUTO,
"low_gain", CTLFLAG_RW,
1543 "What gain percent do we need to see to stay in the lower gain startup??");
1545 SYSCTL_CHILDREN(bbr_startup),
1546 OID_AUTO,
"loss_exit", CTLFLAG_RW,
1548 "Should we exit startup at loss in an epoch if we are not gaining?");
1554 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
1557 SYSCTL_CHILDREN(bbr_cwnd),
1558 OID_AUTO,
"tar_rtt", CTLFLAG_RW,
1560 "Target cwnd rtt measurement to use (0=rtt_prop, 1=rtt_rack, 2=pkt_rtt, 3=srtt)?");
1562 SYSCTL_CHILDREN(bbr_cwnd),
1563 OID_AUTO,
"may_shrink", CTLFLAG_RW,
1565 "Can the cwnd shrink if it would grow to more than the target?");
1567 SYSCTL_CHILDREN(bbr_cwnd),
1568 OID_AUTO,
"max_target_limit", CTLFLAG_RW,
1570 "Do we limit the cwnd to some multiple of the cwnd target if cwnd can't shrink 0=no?");
1572 SYSCTL_CHILDREN(bbr_cwnd),
1573 OID_AUTO,
"highspeed_min", CTLFLAG_RW,
1575 "What is the high-speed min cwnd (rttProp under 1ms)");
1577 SYSCTL_CHILDREN(bbr_cwnd),
1578 OID_AUTO,
"lowspeed_min", CTLFLAG_RW,
1580 "What is the min cwnd (rttProp > 1ms)");
1582 SYSCTL_CHILDREN(bbr_cwnd),
1583 OID_AUTO,
"initwin", CTLFLAG_RW,
1585 "What is the BBR initial window, if 0 use tcp version");
1587 SYSCTL_CHILDREN(bbr_cwnd),
1588 OID_AUTO,
"do_loss_red", CTLFLAG_RW,
1590 "Do we reduce the b/w at exit from recovery based on ratio of prop/srtt (800=80.0, 0=off)?");
1592 SYSCTL_CHILDREN(bbr_cwnd),
1593 OID_AUTO,
"red_scale", CTLFLAG_RW,
1595 "What RTT do we scale with?");
1597 SYSCTL_CHILDREN(bbr_cwnd),
1598 OID_AUTO,
"red_growslow", CTLFLAG_RW,
1600 "Do we restrict cwnd growth for whats in flight?");
1602 SYSCTL_CHILDREN(bbr_cwnd),
1603 OID_AUTO,
"red_div", CTLFLAG_RW,
1605 "If we reduce whats the divisor?");
1607 SYSCTL_CHILDREN(bbr_cwnd),
1608 OID_AUTO,
"red_mul", CTLFLAG_RW,
1610 "If we reduce whats the mulitiplier?");
1612 SYSCTL_CHILDREN(bbr_cwnd),
1613 OID_AUTO,
"target_is_unit", CTLFLAG_RW,
1615 "Is the state target the pacing_gain or BBR_UNIT?");
1617 SYSCTL_CHILDREN(bbr_cwnd),
1618 OID_AUTO,
"drop_limit", CTLFLAG_RW,
1620 "Number of segments limit for drop (0=use min_cwnd w/flight)?");
1627 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
1628 "Time out controls");
1630 SYSCTL_CHILDREN(bbr_timeout),
1631 OID_AUTO,
"delack", CTLFLAG_RW,
1633 "BBR's delayed ack time");
1635 SYSCTL_CHILDREN(bbr_timeout),
1636 OID_AUTO,
"tlp_uses", CTLFLAG_RW,
1638 "RTT that TLP uses in its calculations, 0=rttProp, 1=Rack_rtt, 2=pkt_rtt and 3=srtt");
1640 SYSCTL_CHILDREN(bbr_timeout),
1641 OID_AUTO,
"persmin", CTLFLAG_RW,
1643 "What is the minimum time in microseconds between persists");
1645 SYSCTL_CHILDREN(bbr_timeout),
1646 OID_AUTO,
"persmax", CTLFLAG_RW,
1648 "What is the largest delay in microseconds between persists");
1650 SYSCTL_CHILDREN(bbr_timeout),
1651 OID_AUTO,
"tlp_minto", CTLFLAG_RW,
1653 "TLP Min timeout in usecs");
1655 SYSCTL_CHILDREN(bbr_timeout),
1656 OID_AUTO,
"tlp_dack_time", CTLFLAG_RW,
1658 "TLP delayed ack compensation value");
1661 OID_AUTO,
"minrto", CTLFLAG_RW,
1663 "Minimum RTO in ms");
1665 SYSCTL_CHILDREN(bbr_timeout),
1666 OID_AUTO,
"maxrto", CTLFLAG_RW,
1668 "Maximum RTO in seconds -- should be at least as large as min_rto");
1670 SYSCTL_CHILDREN(bbr_timeout),
1671 OID_AUTO,
"tlp_retry", CTLFLAG_RW,
1673 "How many times does TLP retry a single segment or multiple with no ACK");
1675 SYSCTL_CHILDREN(bbr_timeout),
1676 OID_AUTO,
"minto", CTLFLAG_RW,
1678 "Minimum rack timeout in useconds");
1680 SYSCTL_CHILDREN(bbr_timeout),
1681 OID_AUTO,
"pktdelay", CTLFLAG_RW,
1683 "Extra RACK time (in useconds) besides reordering thresh");
1685 SYSCTL_CHILDREN(bbr_timeout),
1686 OID_AUTO,
"incr_tmrs", CTLFLAG_RW,
1688 "Increase the RXT/TLP timer by the pacing time used?");
1690 SYSCTL_CHILDREN(bbr_timeout),
1691 OID_AUTO,
"rxtmark_sackpassed", CTLFLAG_RW,
1693 "Mark sack passed on all those not ack'd when a RXT hits?");
1699 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
1700 "Policer controls");
1702 SYSCTL_CHILDREN(bbr_policer),
1703 OID_AUTO,
"detect_enable", CTLFLAG_RW,
1705 "Is policer detection enabled??");
1707 SYSCTL_CHILDREN(bbr_policer),
1708 OID_AUTO,
"min_pes", CTLFLAG_RW,
1710 "Minimum number of PE's?");
1712 SYSCTL_CHILDREN(bbr_policer),
1713 OID_AUTO,
"bwdiff", CTLFLAG_RW,
1715 "Minimal bw diff?");
1717 SYSCTL_CHILDREN(bbr_policer),
1718 OID_AUTO,
"bwratio", CTLFLAG_RW,
1720 "Minimal bw diff?");
1722 SYSCTL_CHILDREN(bbr_policer),
1723 OID_AUTO,
"from_rack_rxt", CTLFLAG_RW,
1725 "Do we call the policer detection code from a rack-timeout?");
1727 SYSCTL_CHILDREN(bbr_policer),
1728 OID_AUTO,
"false_postive", CTLFLAG_RW,
1730 "What packet epoch do we do false-postive detection at (0=no)?");
1732 SYSCTL_CHILDREN(bbr_policer),
1733 OID_AUTO,
"loss_thresh", CTLFLAG_RW,
1735 "Loss threshold 196 = 19.6%?");
1737 SYSCTL_CHILDREN(bbr_policer),
1738 OID_AUTO,
"false_postive_thresh", CTLFLAG_RW,
1740 "What percentage is the false detection threshold (150=15.0)?");
1744 OID_AUTO,
"cheat_rxt", CTLFLAG_RW,
1746 "Do we burst 1ms between sends on retransmissions (like rack)?");
1749 OID_AUTO,
"error_paceout", CTLFLAG_RW,
1751 "When we hit an error what is the min to pace out in usec's?");
1754 OID_AUTO,
"kill_paceout", CTLFLAG_RW,
1756 "When we hit this many errors in a row, kill the session?");
1759 OID_AUTO,
"data_after_close", CTLFLAG_RW,
1761 "Do we hold off sending a RST until all pending data is ack'd");
1764 OID_AUTO,
"resend_use_tso", CTLFLAG_RW,
1766 "Can resends use TSO?");
1769 OID_AUTO,
"sblklimit", CTLFLAG_RW,
1771 "When do we start ignoring small sack blocks");
1774 OID_AUTO,
"bb_verbose", CTLFLAG_RW,
1776 "Should BBR black box logging be verbose");
1779 OID_AUTO,
"reorder_thresh", CTLFLAG_RW,
1781 "What factor for rack will be added when seeing reordering (shift right)");
1784 OID_AUTO,
"reorder_fade", CTLFLAG_RW,
1786 "Does reorder detection fade, if so how many ms (0 means never)");
1789 OID_AUTO,
"rtt_tlp_thresh", CTLFLAG_RW,
1791 "what divisor for TLP rtt/retran will be added (1=rtt, 2=1/2 rtt etc)");
1798 OID_AUTO,
"enob_hdwr_pacing", CTLFLAG_RD,
1800 "Total number of enobufs for hardware paced flows");
1803 OID_AUTO,
"enob_no_hdwr_pacing", CTLFLAG_RD,
1805 "Total number of enobufs for non-hardware paced flows");
1810 OID_AUTO,
"hdwr_pacing", CTLFLAG_RD,
1812 "Total number of hardware paced flows");
1816 OID_AUTO,
"software_pacing", CTLFLAG_RD,
1818 "Total number of software paced flows");
1821 OID_AUTO,
"stats", CTLFLAG_RD,
1825 OID_AUTO,
"opts", CTLFLAG_RD,
1829 OID_AUTO,
"lost", CTLFLAG_RD,
1833 OID_AUTO,
"stateresend", CTLFLAG_RD,
1837 OID_AUTO,
"statetime", CTLFLAG_RD,
1841 OID_AUTO,
"outsize", CTLFLAG_RD,
1845 OID_AUTO,
"clrlost", CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_MPSAFE,
1910 0, &log,
false, &bbr->
rc_tv);
1928 0, &log,
false, &bbr->
rc_tv);
1954 tlen, &log,
false, &bbr->
rc_tv);
1972 0, &log,
false, &bbr->
rc_tv);
1991 0, &log,
false, &bbr->
rc_tv);
2000 struct sockbuf *r, *s;
2013 0, &log,
false, &tv);
2038 0, &log,
false, &bbr->
rc_tv);
2057 0, &log,
false, &bbr->
rc_tv);
2080 0, &log,
false, &bbr->
rc_tv);
2108 0, &log,
false, &bbr->
rc_tv);
2132 0, &log,
false, &bbr->
rc_tv);
2150 0, &log,
false, &bbr->
rc_tv);
2173 0, &log,
false, &bbr->
rc_tv);
2201 0, &log,
false, &bbr->
rc_tv);
2219 0, &log,
false, &bbr->
rc_tv);
2238 0, &log,
false, &bbr->
rc_tv);
2257 if (m->m_flags & M_TSTMP) {
2258 mbuf_tstmp2timespec(m, &ts);
2259 tv.tv_sec = ts.tv_sec;
2260 tv.tv_usec = ts.tv_nsec / 1000;
2265 if (m->m_flags & M_TSTMP_LRO) {
2266 tv.tv_sec = m->m_pkthdr.rcv_tstmp / 1000000000;
2267 tv.tv_usec = (m->m_pkthdr.rcv_tstmp % 1000000000) / 1000;
2288 tlen, &log,
true, &bbr->
rc_tv);
2312 0, &log,
true, &bbr->
rc_tv);
2332 len, &log,
true, &bbr->
rc_tv);
2354 0, &log,
false, &bbr->
rc_tv);
2371 ar &= 0x00000000ffffffff;
2374 ar &= 0x00000000ffffffff;
2382 0, &log,
false, &bbr->
rc_tv);
2405 0, &log,
false, &bbr->
rc_tv);
2441 0, &log,
false, &bbr->
rc_tv);
2464 0, &log,
false, &bbr->
rc_tv);
2491 len, &log,
false, &bbr->
rc_tv);
2515 0, &log,
false, &bbr->
rc_tv);
2538 0, &log,
false, &bbr->
rc_tv);
2561 0, &log,
false, &bbr->
rc_tv);
2574 log.
u_bbr.
flex3 = (peer_delta & 0x00000000ffffffff);
2576 log.
u_bbr.
flex5 = (delta & 0x00000000ffffffff);
2583 0, &log,
false, &bbr->
rc_tv);
2611 0, &log,
false, &bbr->
rc_tv);
2637 0, &log,
false, &bbr->
rc_tv);
2670 flex2, &log,
false, &bbr->
rc_tv);
2700 0, &log,
false, &bbr->
rc_tv);
2720 0, &log,
false, &bbr->
rc_tv);
2726 uint64_t rate, uint64_t hw_rate,
int line,
uint32_t cts,
2733 log.
u_bbr.
flex1 = ((hw_rate >> 32) & 0x00000000ffffffff);
2734 log.
u_bbr.
flex2 = (hw_rate & 0x00000000ffffffff);
2735 log.
u_bbr.
flex3 = (((uint64_t)ifp >> 32) & 0x00000000ffffffff);
2736 log.
u_bbr.
flex4 = ((uint64_t)ifp & 0x00000000ffffffff);
2750 0, &log,
false, &bbr->
rc_tv);
2773 len, &log,
false, &bbr->
rc_tv);
2796 0, &log,
false, &bbr->
rc_tv);
2819 0, &log,
false, &bbr->
rc_tv);
2842 0, &log,
false, &bbr->
rc_tv);
2849static inline uint64_t
2874 calclr *= (uint64_t)1000;
2875 calclr /= (uint64_t)del;
2922static inline uint64_t
2925 uint64_t bw, min_bw;
2927 int gm_measure_cnt = 1;
2940 if (rtt && (rtt < 0xffffffff)) {
2943 ((uint64_t)1000000);
2964 if (gm_measure_cnt &&
2971 if (rtt && (rtt < 0xffffffff)) {
2978 ((uint64_t)1000000);
3010 goto use_initial_window;
3020static inline uint64_t
3133 uint64_t del_time, bw, lost, delivered;
3182 if ((delivered == 0) ||
3202 if (loss_detected == 0)
3252 if (loss_detected == 0) {
3260 if ((delivered == 0) ||
3265 if (d_time < 1000) {
3294 rsm = uma_zalloc(
bbr_zone, (M_NOWAIT | M_ZERO));
3346 if (rsm != NULL && limit_type) {
3397 uint64_t usec_per_sec;
3400 return ((rtt * bw) / usec_per_sec);
3484 if ((cwnd / mss) & 0x1) {
3517 seg_oh +=
sizeof(
struct ip6_hdr);
3523 seg_oh +=
sizeof(
struct ip);
3529 seg_oh +=
sizeof(
struct ether_header);
3537 uint64_t divor, res, tim;
3539 if (useconds_time == 0)
3543 tim = useconds_time;
3544 res = (tim * bw * gain) / divor;
3558 uint64_t bw, lentim, res;
3566 num_segs = (len + maxseg - 1) / maxseg;
3569 len += (num_segs * seg_oh);
3581 cbw /= (uint64_t)1000;
3586 lentim = ((uint64_t)len *
3589 res = lentim / ((uint64_t)gain * bw);
3615 uint32_t cwnd, target_cwnd, saved_bytes, maxseg;
3628 int64_t gput, time_stamp;
3630 gput = (int64_t) (th->th_ack - tp->
gput_seq) * 8;
3632 cgput = gput / time_stamp;
3636 stats_voi_update_abs_s32(tp->
t_stats,
3640 tp->
t_flags &= ~TF_GPUTINPROG;
3650 saved_bytes = bytes_this_ack;
3651 bytes_this_ack += sack_changed;
3652 if (bytes_this_ack > prev_acked) {
3653 bytes_this_ack -= prev_acked;
3659 bytes_this_ack = maxseg;
3688 if (cwnd > losses) {
3697 losses, 10, 0, 0, line);
3710 if ((flight + bytes_this_ack) > cwnd)
3711 cwnd = flight + bytes_this_ack;
3716 prev_acked, 1, target_cwnd, th->th_ack, line);
3724 if (bytes_this_ack > maxseg)
3725 bytes_this_ack = maxseg;
3736 s_cwnd = min((cwnd + bytes_this_ack), target_cwnd);
3746 if ((cwnd < target_cwnd) ||
3749 cwnd += bytes_this_ack;
3759 bbr_log_type_cwndupd(bbr, saved_bytes, sack_changed, prev_acked, meth, target_cwnd, th->th_ack, line);
3818 uint64_t val, lr2use;
3819 uint32_t maxseg, newcwnd, acks_inflight, ratio, cwnd;
3865 acks_inflight = (flight / (maxseg * 2));
3874 val = (uint64_t)cwnd * lr2use;
3877 newcwnd = roundup((cwnd - val), maxseg);
3883 newcwnd = roundup((
uint32_t)val, maxseg);
3891 if ((newcwnd + (acks_inflight * maxseg)) <
get_min_cwnd(bbr)) {
3914 if (flight <= tp->snd_cwnd) {
4032#define DELAY_ACK(tp, bbr, nsegs) \
4033 (((tp->t_flags & TF_RXWIN0SENT) == 0) && \
4034 ((tp->t_flags & TF_DELACK) == 0) && \
4035 ((bbr->bbr_segs_rcvd + nsegs) < tp->t_delayed_ack) && \
4036 (tp->t_delayed_ack || (tp->t_flags & TF_NEEDSYN)))
4076 TAILQ_FOREACH_REVERSE_FROM(prsm, &bbr->
r_ctl.
rc_map, bbr_head, r_next) {
4147 thresh += (srtt >> 2);
4152 if ((bbr->
rc_tp)->t_srtt == 0)
4156 if (thresh > t_rxtcur) {
4177 uint32_t thresh, len, maxseg, t_rxtcur;
4185 thresh = (srtt * 2);
4191 prsm = TAILQ_PREV(rsm, bbr_head, r_tnext);
4192 if (prsm && (len <= maxseg)) {
4206 thresh += inter_gap;
4207 }
else if (len <= maxseg) {
4214 if (alt_thresh > thresh)
4215 thresh = alt_thresh;
4221 t_rxtcur = TICKS_2_USEC(tp->
t_rxtcur);
4225 if (thresh > t_rxtcur) {
4283#ifdef BBR_INVARIANTS
4284 panic(
"Unknown rtt request type %d", rtt_type);
4356#ifdef BBR_INVARIANTS
4358 panic(
"tp:%p bbr:%p rsm:%p length is 0?", tp, bbr, rsm);
4417 nrsm->
r_flags &= ~BBR_HAS_SYN;
4433 for (idx = 0; idx < nrsm->
r_rtr_cnt; idx++) {
4469 l_rsm = TAILQ_PREV(at, bbr_head, r_next);
4470 r_rsm = TAILQ_NEXT(at, r_next);
4473 if ((l_rsm->
r_end == start) ||
4488 if ((r_rsm->
r_start == end) ||
4570 int collapsed_win = 0;
4581 return (-ETIMEDOUT);
4596 avail = sbavail(&so->so_snd);
4613 if ((out + amm) <= tp->
snd_wnd) {
4630 if (collapsed_win == 0) {
4643 TAILQ_FOREACH_REVERSE(rsm, &bbr->
r_ctl.
rc_map, bbr_head, r_next) {
4672 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_map, rsm, nrsm, r_next);
4674 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_tmap, rsm, nrsm, r_tnext);
4677 rsm->
r_flags &= (~BBR_HAS_FIN);
4760 (
"%s: tp %p tp->t_inpcb == NULL", __func__, tp));
4773 return (-ETIMEDOUT);
4786 return (-ETIMEDOUT);
4802 return (-ETIMEDOUT);
4807 &t_template->
tt_t, (
struct mbuf *)NULL,
4812 free(t_template, M_TEMP);
4864 &t_template->
tt_t, (
struct mbuf *)NULL,
4866 free(t_template, M_TEMP);
4874 return (-ETIMEDOUT);
4908 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_tmap, trsm, rsm, r_tnext);
4936 rsm->
r_flags &= ~BBR_WAS_SACKPASS;
4946 rsm->
r_flags &= ~BBR_WAS_SACKPASS;
4947 rsm->
r_flags &= ~BBR_SACK_PASSED;
4995 return (-ETIMEDOUT);
5110 }
else if (isipv6) {
5121#if defined(INET6) && defined(INET)
5152 tp->
t_flags2 &= ~TF2_PLPMTU_BLACKHOLE;
5215 if (hpts_calling == 0) {
5274 time_since_send = 0;
5331 if ((rsm == NULL) || (u_rsm == rsm))
5350 rsm->
r_flags &= ~BBR_RWND_COLLAPSED;
5354 rsm->
r_flags &= ~BBR_MARKED_LOST;
5366 rsm->
r_flags &= ~BBR_RXT_CLEARED;
5405 rsm->
r_flags &= ~BBR_SACK_PASSED;
5451 if (c_end == rsm->
r_end) {
5459 *lenp = (len - act_len);
5460 return (rsm->
r_end);
5481 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_map, rsm, nrsm, r_next);
5484 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_tmap, rsm, nrsm, r_tnext);
5487 rsm->
r_flags &= (~BBR_HAS_FIN);
5506 uint64_t act_rate, uint64_t rate_wanted)
5532 int error,
rate = -1;
5599 uint32_t cur_delay, seg_sz, maxseg, new_tso, delta, hdwr_delay;
5628 if (cur_delay > hdwr_delay)
5629 delta = cur_delay - hdwr_delay;
5664 }
else if (delta == 0) {
5825 if (bytes > (64 * 1024))
5827 new_tso = bytes / maxseg;
5832 if (new_tso < min_tso_segs)
5833 new_tso = min_tso_segs;
5845 if (tso_len > maxseg) {
5846 new_tso = tso_len / maxseg;
5857 new_tso = rounddown(tso_len, min_tso);
5882 new_tso = roundup(bw, (uint64_t)maxseg);
5899 if (old_tso != new_tso) {
5916 register uint32_t snd_max, snd_una;
5942 if (th_flags & TH_RST) {
5951 if (th_flags & (TH_SYN | TH_FIN) && (hintrsm == NULL)) {
5958 if ((th_flags & TH_SYN) && (tp->
iss == seq_out))
5960 if (th_flags & TH_FIN)
5963 if (
SEQ_LEQ((seq_out + len), snd_una)) {
5967 if (
SEQ_LT(seq_out, snd_una)) {
5971 end = seq_out + len;
5973 len = end - seq_out;
5982 if (seq_out == snd_max) {
5989 if (th_flags & TH_SYN)
5991 if (th_flags & TH_FIN)
6017 TAILQ_INSERT_TAIL(&bbr->
r_ctl.
rc_map, rsm, r_next);
6040 if (hintrsm && (hintrsm->
r_start == seq_out)) {
6050 if ((rsm) && (rsm->
r_start == seq_out)) {
6064 if (rsm->
r_start == seq_out) {
6089 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_map, rsm, nrsm, r_next);
6091 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_tmap, rsm, nrsm, r_tnext);
6094 rsm->
r_flags &= (~BBR_HAS_FIN);
6108#ifdef BBR_INVARIANTS
6109 printf(
"seq_out:%u len:%d snd_una:%u snd_max:%u -- but rsm not found?\n",
6111 printf(
"Starting Dump of all rack entries\n");
6113 printf(
"rsm:%p start:%u end:%u\n",
6116 printf(
"Dump complete\n");
6117 panic(
"seq_out not found rack:%p tp:%p",
6121#ifdef BBR_INVARIANTS
6126 panic(
"seq_out:%u(%d) is beyond snd_max:%u tp:%p",
6127 seq_out, len, tp->
snd_max, tp);
6191 uint64_t delta, peer_delta, delta_up;
6218 if (peer_delta > delta) {
6224 if (peer_delta < (delta + ((delta * (uint64_t)1000)/ (uint64_t)
bbr_delta_percent))) {
6238 if ((peer_delta + delta_up) >= delta) {
6246 if (((peer_delta * 10) + delta_up) >= delta) {
6253 if (((peer_delta * 100) + delta_up) >= delta) {
6260 if (((peer_delta * 1000) + delta_up) >= delta) {
6267 if (((peer_delta * 10000) + delta_up) >= delta) {
6311 filter_increase_by_small(&bbr->
r_ctl.
rc_rttprop, (rtt - rtt_prop), cts);
6483 }
else if ((orig_bw == 0) && get_filter_value(&bbr->
r_ctl.
rc_delrate))
6493 uint64_t tim, bw, ts_diff, ts_bw;
6506 bw = (uint64_t)delivered;
6524 if ((delivered == 0) ||
6531 0, 0, 0, delivered);
6533 ts_bw = (uint64_t)delivered;
6538 (ts_bw & 0xffffffff), 0, 0,
6539 0, 0, ts_diff, delivered);
6546 (bw & 0x00000000ffffffff),
6549 }
else if (ts_bw && (ts_bw < bw)) {
6554 (bw & 0x00000000ffffffff),
6621 bw = (uint64_t)delivered;
6674 if ((no_apply == 0) &&
6688 uint64_t old_rttprop;
6738 if (rtt < old_rttprop) {
6909#ifdef BBR_INVARIANTS
6911 panic(
"rsm:%p bbr:%p rsm has overmax and only 1 retranmit flags:%x?", rsm, bbr, rsm->
r_flags);
6959 bbr_head, r_tnext) {
6984 nrsm->
r_flags &= ~BBR_WAS_SACKPASS;
6999 int32_t used_ref = 1;
7000 uint8_t went_back = 0, went_fwd = 0;
7002 start = sack->
start;
7011 TAILQ_FOREACH_REVERSE_FROM(rsm, &bbr->
r_ctl.
rc_map, bbr_head, r_next) {
7024 TAILQ_FOREACH_FROM(rsm, &bbr->
r_ctl.
rc_map, r_next) {
7054#ifdef BBR_INVARIANTS
7055 panic(
"tp:%p bbr:%p sack:%p to:%p prsm:%p",
7056 tp, bbr, sack, to, prsm);
7064 goto start_at_beginning;
7085 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_map, rsm, nrsm, r_next);
7087 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_tmap, rsm, nrsm, r_tnext);
7090 rsm->
r_flags &= (~BBR_HAS_FIN);
7131 nrsm = TAILQ_NEXT(rsm, r_next);
7157 rsm->
r_flags &= (~BBR_HAS_FIN);
7158 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_map, rsm, nrsm, r_next);
7160 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_tmap, rsm, nrsm, r_tnext);
7196 nrsm = TAILQ_NEXT(rsm, r_next);
7203 nrsm = TAILQ_PREV(rsm, bbr_head, r_next);
7210 if (used_ref == 0) {
7215 if (went_fwd && went_back) {
7217 }
else if (went_fwd) {
7219 }
else if (went_back) {
7242#ifdef BBR_INVARIANTS
7244 panic(
"bbr:%p rsm:%p flags:0x%x in tmap?",
7265 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_tmap, tmap, rsm, r_tnext);
7277 rsm = TAILQ_NEXT(rsm, r_next);
7330 uint32_t changed, last_seq, entered_recovery = 0;
7333 struct sackblk sack, sack_blocks[TCP_MAX_SACK + 1];
7335 int32_t i, j, k, new_sb, num_sack_blks = 0;
7336 uint32_t cts, acked, ack_point, sack_changed = 0;
7337 uint32_t p_maxseg, maxseg, p_acked = 0;
7351 th_ack = th->th_ack;
7363 changed = th_ack - rsm->
r_start;
7364 }
else if ((rsm == NULL) && ((th_ack - 1) == tp->
iss)) {
7391 }
else if (rsm == NULL) {
7407#ifdef BBR_INVARIANTS
7408 panic(
"No rack map tp:%p for th:%p state:%d bbr:%p snd_una:%u snd_max:%u chg:%d\n",
7418#ifdef BBR_INVARIANTS
7419 printf(
"Rack map starts at r_start:%u for th_ack:%u huh? ts:%d rs:%d bbr:%p\n",
7423 panic(
"th-ack is bad bbr:%p tp:%p", bbr, tp);
7426 }
else if (th_ack == rsm->
r_start) {
7470 rsm->
r_flags &= ~BBR_MARKED_LOST;
7485 left = th_ack - rsm->
r_end;
7510 lrsm.
r_end = th_ack;
7551 last_seq = rsm->
r_end;
7561 bcopy((to->
to_sacks + i * TCPOLEN_SACK),
7562 &sack,
sizeof(sack));
7564 sack.
end = ntohl(sack.
end);
7572 ((sack.
end - sack.
start) < (p_maxseg / 8))) {
7580 sack_blocks[num_sack_blks] = sack;
7590 if (num_sack_blks == 0)
7597 num_sack_blks, th->th_ack);
7600 BBR_STAT_ADD(bbr_sack_blocks_skip, (num_sack_blks - new_sb));
7601 num_sack_blks = new_sb;
7602 if (num_sack_blks < 2) {
7606 for (i = 0; i < num_sack_blks; i++) {
7607 for (j = i + 1; j < num_sack_blks; j++) {
7608 if (
SEQ_GT(sack_blocks[i].end, sack_blocks[j].end)) {
7609 sack = sack_blocks[i];
7610 sack_blocks[i] = sack_blocks[j];
7611 sack_blocks[j] = sack;
7620 if (num_sack_blks > 1) {
7621 for (i = 0; i < num_sack_blks; i++) {
7622 for (j = i + 1; j < num_sack_blks; j++) {
7623 if (sack_blocks[i].end == sack_blocks[j].end) {
7630 if (
SEQ_LT(sack_blocks[j].start, sack_blocks[i].start)) {
7641 for (k = (j + 1); k < num_sack_blks; k++) {
7643 sack_blocks[j].
end = sack_blocks[k].
end;
7654 for (i = 0; i < num_sack_blks; i++) {
7659 sack_changed += acked;
7663 *prev_acked = p_acked;
7674 entered_recovery = 1;
7700 return (sack_changed);
7709 if (rsm && (rsm->
r_dupack < 0xff)) {
7726 int32_t * ofia, int32_t thflags, int32_t * ret_val)
7728 int32_t ourfinisacked = 0;
7729 int32_t acked_amount;
7739 nsegs = max(1, m->m_pkthdr.lro_nsegs);
7751 sack_changed =
bbr_log_ack(tp, to, th, &prev_acked);
7759 if (th->th_ack == tp->
snd_una) {
7815 SOCKBUF_LOCK(&so->so_snd);
7816 acked_amount = min(acked, (
int)sbavail(&so->so_snd));
7818 mfree = sbcut_locked(&so->so_snd, acked_amount);
7820 sowwakeup_locked(so);
7847 if ((sbused(&so->so_snd) == 0) &&
7863 (sbavail(&so->so_snd) == 0) &&
7882 *ofia = ourfinisacked;
8036 rsm->
r_flags &= ~BBR_RWND_COLLAPSED;
8056 if ((max_seq != rsm->
r_start) &&
8057 (max_seq != rsm->
r_end)){
8061 res1 = max_seq - rsm->
r_start;
8062 res2 = rsm->
r_end - max_seq;
8063 if ((res1 >= (maxseg/8)) &&
8064 (res2 >= (maxseg/8))) {
8073 if (max_seq == rsm->
r_start) {
8076 }
else if (max_seq == rsm->
r_end) {
8078 nrsm = TAILQ_NEXT(rsm, r_next);
8083 }
else if (can_split &&
SEQ_LT(max_seq, rsm->
r_end)) {
8094 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_map, rsm, nrsm, r_next);
8096 TAILQ_INSERT_AFTER(&bbr->
r_ctl.
rc_tmap, rsm, nrsm, r_tnext);
8110 TAILQ_FOREACH_FROM(nrsm, &bbr->
r_ctl.
rc_map, r_next) {
8124 TAILQ_FOREACH_REVERSE(rsm, &bbr->
r_ctl.
rc_map, bbr_head, r_next) {
8127 rsm->
r_flags &= ~BBR_RWND_COLLAPSED;
8144 struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen,
8145 uint32_t tiwin, int32_t thflags, int32_t nxt_pkt)
8157 nsegs = max(1, m->m_pkthdr.lro_nsegs);
8158 if ((thflags & TH_ACK) &&
8172 }
else if (thflags & TH_ACK) {
8173 if ((tp->
snd_wl2 == th->th_ack) && (tiwin < tp->snd_wnd)) {
8230 if ((tlen || (thflags & TH_FIN) || (tfo_syn && tlen > 0)) &&
8232 tcp_seq save_start = th->th_seq;
8233 tcp_seq save_rnxt = tp->
rcv_nxt;
8234 int save_tlen = tlen;
8236 m_adj(m, drop_hdrlen);
8248 if (th->th_seq == tp->
rcv_nxt &&
8252#ifdef NETFLIX_SB_LIMITS
8253 u_int mcnt, appended;
8255 if (so->so_rcv.sb_shlim) {
8258 if (counter_fo_get(so->so_rcv.sb_shlim, mcnt,
8259 CFO_NOSLEEP, NULL) ==
false) {
8260 counter_u64_add(tcp_sb_shlim_fails, 1);
8267 if (
DELAY_ACK(tp, bbr, nsegs) || tfo_syn) {
8288 SOCKBUF_LOCK(&so->so_rcv);
8289 if (so->so_rcv.sb_state & SBS_CANTRCVMORE)
8292#ifdef NETFLIX_SB_LIMITS
8295 sbappendstream_locked(&so->so_rcv, m, 0);
8297 sorwakeup_locked(so);
8298#ifdef NETFLIX_SB_LIMITS
8299 if (so->so_rcv.sb_shlim && appended != mcnt)
8300 counter_fo_release(so->so_rcv.sb_shlim,
8311 tcp_seq temp = save_start;
8313 thflags =
tcp_reass(tp, th, &temp, &tlen, m);
8318 sorwakeup_locked(so);
8324 if ((tlen == 0) && (
SEQ_LT(save_start, save_rnxt))) {
8330 save_start + save_tlen);
8343 save_start + save_tlen);
8345 }
else if (tlen >= save_tlen) {
8348 save_start + save_tlen);
8349 }
else if (tlen > 0) {
8363 if (thflags & TH_FIN) {
8436 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
8440 int32_t newsize = 0;
8442#ifdef NETFLIX_SB_LIMITS
8443 u_int mcnt, appended;
8451 struct tcphdr tcp_savetcp;
8466 if (tiwin && tiwin != tp->
snd_wnd) {
8476 if (__predict_false((th->th_ack != tp->
snd_una))) {
8479 if (__predict_false(tlen > sbspace(&so->so_rcv))) {
8491 nsegs = max(1, m->m_pkthdr.lro_nsegs);
8493#ifdef NETFLIX_SB_LIMITS
8494 if (so->so_rcv.sb_shlim) {
8497 if (counter_fo_get(so->so_rcv.sb_shlim, mcnt,
8498 CFO_NOSLEEP, NULL) ==
false) {
8499 counter_u64_add(tcp_sb_shlim_fails, 1);
8530 if (so->so_options & SO_DEBUG)
8532 (
void *)tcp_saveipgen, &tcp_savetcp, 0);
8537 SOCKBUF_LOCK(&so->so_rcv);
8538 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
8546 if (!sbreserve_locked(&so->so_rcv,
8548 so->so_rcv.sb_flags &= ~SB_AUTOSIZE;
8549 m_adj(m, drop_hdrlen);
8551#ifdef NETFLIX_SB_LIMITS
8554 sbappendstream_locked(&so->so_rcv, m, 0);
8558 sorwakeup_locked(so);
8559#ifdef NETFLIX_SB_LIMITS
8560 if (so->so_rcv.sb_shlim && mcnt != appended)
8561 counter_fo_release(so->so_rcv.sb_shlim, mcnt - appended);
8586 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
8598 struct tcphdr tcp_savetcp;
8613 if (__predict_false(tiwin == 0)) {
8643 nsegs = max(1, m->m_pkthdr.lro_nsegs);
8644 sack_changed =
bbr_log_ack(tp, to, th, &prev_acked);
8710 hhook_run_tcp_est_in(tp, th, to);
8715 sbdrop(&so->so_snd, acked);
8729 bbr_ack_received(tp, bbr, th, acked, sack_changed, prev_acked, __LINE__, 0);
8743 if (so->so_options & SO_DEBUG)
8745 (
void *)tcp_saveipgen,
8768 if (sbavail(&so->so_snd)) {
8781 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
8785 int32_t ourfinisacked = 0;
8787 int32_t ret_val = 0;
8802 if ((thflags & TH_ACK) &&
8809 if ((thflags & (TH_ACK | TH_RST)) == (TH_ACK | TH_RST)) {
8811 mtod(m,
const char *), tp, th);
8816 if (thflags & TH_RST) {
8820 if (!(thflags & TH_SYN)) {
8824 tp->
irs = th->th_seq;
8826 if (thflags & TH_ACK) {
8827 int tfo_partial = 0;
8832 mac_socketpeer_set_from_mbuf(m, so);
8854 if (
DELAY_ACK(tp, bbr, 1) && tlen != 0 && !tfo_partial) {
8896 mtod(m,
const char *), tp, th);
8933 if (thflags & TH_ACK) {
8949 if (
bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val))
8958 if (ourfinisacked) {
8969 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
8970 soisdisconnected(so);
8981 tiwin, thflags, nxt_pkt));
8991 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
8994 int32_t ourfinisacked = 0;
9000 if ((thflags & TH_ACK) &&
9014 if ((thflags & (TH_SYN | TH_ACK)) == (TH_SYN | TH_ACK)) {
9018 }
else if (thflags & TH_SYN) {
9026 }
else if (!(thflags & (TH_ACK | TH_FIN | TH_RST))) {
9031 if ((thflags & TH_RST) ||
9056 if (
ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
9076 ((thflags & (TH_SYN | TH_FIN)) != 0))) {
9086 if ((thflags & TH_ACK) == 0) {
9091 tiwin, thflags, nxt_pkt));
9119 if (thflags & TH_ACK)
9136 mtod(m,
const char *), tp, th);
9157 if (tlen == 0 && (thflags & TH_FIN) == 0) {
9158 (void)
tcp_reass(tp, (
struct tcphdr *)0, NULL, 0,
9163 sorwakeup_locked(so);
9167 if (
bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) {
9177 if (ourfinisacked) {
9187 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
9188 soisdisconnected(so);
9198 tiwin, thflags, nxt_pkt));
9208 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
9238 __predict_true((thflags & (TH_SYN | TH_FIN | TH_RST | TH_URG | TH_ACK)) == TH_ACK) &&
9240 __predict_true(th->th_seq == tp->
rcv_nxt)) {
9242 if (
bbr_fastack(m, th, so, tp, to, drop_hdrlen, tlen,
9243 tiwin, nxt_pkt, iptos)) {
9255 if ((thflags & TH_RST) ||
9262 if (thflags & TH_SYN) {
9276 if (
ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
9296 ((thflags & (TH_SYN | TH_FIN)) != 0))) {
9305 if ((thflags & TH_ACK) == 0) {
9308 tiwin, thflags, nxt_pkt));
9321 if (
bbr_process_ack(m, th, so, tp, to, tiwin, tlen, NULL, thflags, &ret_val)) {
9324 if (sbavail(&so->so_snd)) {
9333 tiwin, thflags, nxt_pkt));
9343 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
9351 if ((thflags & TH_RST) ||
9358 if (thflags & TH_SYN) {
9372 if (
ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
9392 ((thflags & (TH_SYN | TH_FIN)) != 0))) {
9401 if ((thflags & TH_ACK) == 0) {
9404 tiwin, thflags, nxt_pkt));
9417 if (
bbr_process_ack(m, th, so, tp, to, tiwin, tlen, NULL, thflags, &ret_val)) {
9420 if (sbavail(&so->so_snd)) {
9428 tiwin, thflags, nxt_pkt));
9433 struct tcpcb *tp, int32_t * tlen,
struct tcphdr *th,
struct socket *so)
9446 if (sbavail(&so->so_snd) == 0)
9449 tp->
rcv_nxt = th->th_seq + *tlen;
9463 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
9466 int32_t ourfinisacked = 0;
9472 if ((thflags & TH_RST) ||
9479 if (thflags & TH_SYN) {
9493 if (
ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
9500 if ((so->so_state & SS_NOFDREF) && tlen) {
9525 ((thflags & (TH_SYN | TH_FIN)) != 0))) {
9534 if ((thflags & TH_ACK) == 0) {
9537 tiwin, thflags, nxt_pkt));
9550 if (
bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) {
9553 if (ourfinisacked) {
9563 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
9564 soisdisconnected(so);
9572 if (sbavail(&so->so_snd)) {
9580 tiwin, thflags, nxt_pkt));
9590 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
9593 int32_t ourfinisacked = 0;
9599 if ((thflags & TH_RST) ||
9606 if (thflags & TH_SYN) {
9620 if (
ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
9627 if ((so->so_state & SS_NOFDREF) && tlen) {
9652 ((thflags & (TH_SYN | TH_FIN)) != 0))) {
9661 if ((thflags & TH_ACK) == 0) {
9664 tiwin, thflags, nxt_pkt));
9677 if (
bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) {
9680 if (ourfinisacked) {
9685 if (sbavail(&so->so_snd)) {
9693 tiwin, thflags, nxt_pkt));
9703 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
9706 int32_t ourfinisacked = 0;
9712 if ((thflags & TH_RST) ||
9719 if (thflags & TH_SYN) {
9733 if (
ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
9740 if ((so->so_state & SS_NOFDREF) && tlen) {
9765 ((thflags & (TH_SYN | TH_FIN)) != 0))) {
9774 if ((thflags & TH_ACK) == 0) {
9777 tiwin, thflags, nxt_pkt));
9790 if (
bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) {
9793 if (ourfinisacked) {
9798 if (sbavail(&so->so_snd)) {
9806 tiwin, thflags, nxt_pkt));
9816 struct tcpcb *tp,
struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen,
9819 int32_t ourfinisacked = 0;
9826 if ((thflags & TH_RST) ||
9834 if (thflags & TH_SYN) {
9849 if (
ctf_drop_checks(to, m, th, tp, &tlen, &thflags, &drop_hdrlen, &ret_val)) {
9857 if ((so->so_state & SS_NOFDREF) &&
9885 ((thflags & (TH_SYN | TH_FIN)) != 0))) {
9894 if ((thflags & TH_ACK) == 0) {
9897 tiwin, thflags, nxt_pkt));
9911 if (
bbr_process_ack(m, th, so, tp, to, tiwin, tlen, &ourfinisacked, thflags, &ret_val)) {
9914 if (sbavail(&so->so_snd)) {
9923 tiwin, thflags, nxt_pkt));
10149#ifdef NETFLIX_PEAKRATE
10177 TAILQ_INSERT_TAIL(&bbr->
r_ctl.
rc_map, rsm, r_next);
10391 uint64_t bw, rate, gain_calc;
10397 gain_calc = (rate *
BBR_UNIT) / bw;
10535 uint32_t flight, bbr_cur_cycle_time;
10813 uint32_t cur_rttp, fval, newval, baseval;
10828 newval = cur_rttp * mul;
10930static int32_t
inline
10950 uint64_t btlbw, gain;
10951 if (pkt_epoch == 0) {
10960 if (btlbw >= gain) {
10973static int32_t
inline
10977 uint64_t btlbw, gain;
10979 int delta, rtt_gain;
11003 if (pkt_epoch == 0) {
11070 if (btlbw >= gain) {
11119#ifdef BBR_INVARIANTS
11346 struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen,
uint8_t iptos,
11347 int32_t nxt_pkt,
struct timeval *tv)
11349 int32_t thflags, retval;
11355 struct timeval ltv;
11356 int32_t did_out = 0;
11358 int32_t prev_state;
11361 nsegs = max(1, m->m_pkthdr.lro_nsegs);
11364 kern_prefetch(bbr, &prev_state);
11390 if (m->m_flags & M_TSTMP) {
11392 struct timespec ts;
11394 mbuf_tstmp2timespec(m, &ts);
11395 bbr->
rc_tv.tv_sec = ts.tv_sec;
11396 bbr->
rc_tv.tv_usec = ts.tv_nsec / 1000;
11398 }
else if (m->m_flags & M_TSTMP_LRO) {
11400 struct timespec ts;
11402 mbuf_tstmp2timespec(m, &ts);
11403 bbr->
rc_tv.tv_sec = ts.tv_sec;
11404 bbr->
rc_tv.tv_usec = ts.tv_nsec / 1000;
11416 (th->th_off << 2) -
sizeof(
struct tcphdr),
11417 (thflags & TH_SYN) ?
TO_SYN : 0);
11430 goto done_with_input;
11454 if (bbr->
rc_inp == NULL) {
11467 tp->
t_flags &= ~TF_REQ_SCALE;
11479 tp->
t_flags &= ~TF_REQ_TSTMP;
11484 tp->
t_flags &= ~TF_SACK_PERMIT;
11520 if (thflags & TH_ACK) {
11532 if (thflags & TH_FIN)
11538 kern_prefetch(rsm, &prev_state);
11543 if (m->m_flags & (M_TSTMP|M_TSTMP_LRO)) {
11561 if ((thflags & TH_SYN) && (thflags & TH_FIN) &&
V_drop_synfin) {
11564 goto done_with_input;
11578#ifdef BBR_INVARIANTS
11581 panic(
"tp:%p bbr:%p given a dropped inp:%p",
11596 tp, &to, drop_hdrlen,
11597 tlen, tiwin, thflags, nxt_pkt, iptos);
11598#ifdef BBR_INVARIANTS
11599 if ((retval == 0) &&
11601 panic(
"retval:%d tp:%p t_inpcb:NULL state:%d",
11602 retval, tp, prev_state);
11619 if (nxt_pkt == 0) {
11623 if (tcp_output(tp) < 0)
11628 if ((nxt_pkt == 0) &&
11663 if (tcp_output(tp) < 0)
11682#ifdef BBR_INVARIANTS
11684 panic(
"OP:%d retval:%d tp:%p t_inpcb:NULL state:%d",
11686 retval, tp, prev_state);
11695 struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen,
uint8_t iptos)
11707 if (m->m_flags & M_TSTMP_LRO) {
11708 tv.tv_sec = m->m_pkthdr.rcv_tstmp /1000000000;
11709 tv.tv_usec = (m->m_pkthdr.rcv_tstmp % 1000000000)/1000;
11715 drop_hdrlen, tlen, iptos, 0, &tv);
11739 if (flight >= sendwin) {
11747 len = sendwin - flight;
11752 if ((len + sb_offset) > avail) {
11757 len = avail - sb_offset;
11766#ifdef NETFLIX_STATS
11785#ifdef NETFLIX_STATS
11887 if (adv >= (2 * maxseg) &&
11888 (adv >= (so->so_rcv.sb_hiwat / 4) ||
11889 recwin <= (so->so_rcv.sb_hiwat / 8) ||
11890 so->so_rcv.sb_hiwat <= 8 * maxseg)) {
11893 if (2 * adv >= (int32_t) so->so_rcv.sb_hiwat)
11912 int32_t flags, abandon, error = 0;
11916 uint32_t if_hw_tsomaxsegcount = 0;
11919 struct ip *
ip = NULL;
11921 struct ipovly *ipov = NULL;
11925 struct udphdr *udp = NULL;
11926 u_char opt[TCP_MAXOLEN];
11927 unsigned ipoptlen, optlen, hdrlen;
11933#ifdef BBR_INVARIANTS
11934 uint8_t doing_retran_from = 0;
11935 uint8_t picked_up_retran = 0;
11939 int32_t prefetch_so_done = 0;
11940 int32_t prefetch_rsm = 0;
11943 uint32_t maxseg, pace_max_segs, p_maxseg;
11944 int32_t csum_flags = 0;
11946#if defined(IPSEC) || defined(IPSEC_SUPPORT)
11947 unsigned ipsec_optlen = 0;
11950 volatile int32_t sack_rxmit;
11956 struct sockbuf *sb;
11966 memcpy(&bbr->
rc_tv, tv,
sizeof(
struct timeval));
11971 if (sb->sb_flags & SB_TLS_IFNET)
11975 kern_prefetch(sb, &maxseg);
11982 p_maxseg = min(maxseg, pace_max_segs);
12013 recwin = lmin(lmax(sbspace(&so->so_rcv), 0),
12016 ((tcp_outflags[tp->
t_state] & TH_RST) == 0) &&
12017 ((sbavail(sb) + ((tcp_outflags[tp->
t_state] & TH_FIN) ? 1 : 0)) <=
12086 uint64_t merged_val;
12159 return (retval < 0 ? retval : 0);
12163 if (hpts_calling &&
12179 goto just_return_nolock;
12198#ifdef BBR_INVARIANTS
12199 doing_retran_from = picked_up_retran = 0;
12207 flags = tcp_outflags[tp->
t_state];
12211 if (flags & TH_RST) {
12226 goto just_return_nolock;
12237#ifdef BBR_INVARIANTS
12238 picked_up_retran = 1;
12245#ifdef BBR_INVARIANTS
12246 doing_retran_from = 1;
12252#ifdef BBR_INVARIANTS
12253 panic(
"Huh, tp:%p bbr:%p rsm:%p start:%u < snd_una:%u\n",
12255 goto recheck_resend;
12259 goto recheck_resend;
12266 if ((flags & TH_SYN) == 0) {
12274 rsm->
r_flags &= ~BBR_HAS_SYN;
12299 goto recheck_resend;
12316#ifdef BBR_INVARIANTS
12317 panic(
"tp:%p bbc:%p snd_una:%u rsm:%p r_start:%u",
12322 goto recheck_resend;
12332 if ((rsm == NULL) &&
12340 goto just_return_nolock;
12342#ifdef BBR_INVARIANTS
12344 panic(
"tp:%p bbr:%p rsm:%p sb_offset:%u len:%u",
12345 tp, bbr, rsm, sb_offset, len);
12369 if (flags & TH_FIN)
12372 if ((sack_rxmit == 0) && (prefetch_rsm == 0)) {
12377 kern_prefetch(end_rsm, &prefetch_rsm);
12396 if (sack_rxmit == 0) {
12399 avail = sbavail(sb);
12411 if (tlplen > (
uint32_t)(avail - sb_offset)) {
12412 tlplen = (
uint32_t)(avail - sb_offset);
12422 if ((len < p_maxseg) &&
12425 ((avail - sb_offset) >= p_maxseg)) {
12477 if (prefetch_so_done == 0) {
12478 kern_prefetch(so, &prefetch_so_done);
12479 prefetch_so_done = 1;
12486 if ((flags & TH_SYN) && (rsm == NULL) &&
12497 sb_offset--, len++;
12498 if (sbavail(sb) == 0)
12500 }
else if ((flags & TH_SYN) && rsm) {
12526 (((flags & TH_SYN) && (tp->
t_rxtshift > 0)) ||
12529 (flags & TH_RST))) {
12557 (sb_offset < (
int)sbavail(sb))) {
12564 }
else if ((rsm == NULL) &&
12565 (doing_tlp == 0) &&
12574 (len < (
int)(sbavail(sb) - sb_offset))) {
12588 (len < (
int)(sbavail(sb) - sb_offset)) &&
12606 (len < (
int)(sbavail(sb) - sb_offset)) &&
12620 KASSERT(len >= 0, (
"[%s:%d]: len < 0", __func__, __LINE__));
12635 if (sbavail(sb) > sb_offset)
12636 sbleft = sbavail(sb) - sb_offset;
12663 ipoptlen = ip6_optlen(inp);
12668 offsetof(
struct ipoption, ipopt_list);
12671#if defined(IPSEC) || defined(IPSEC_SUPPORT)
12677 if (isipv6 && IPSEC_ENABLED(ipv6))
12678 ipsec_optlen = IPSEC_HDRSIZE(ipv6, inp);
12684 if (IPSEC_ENABLED(ipv4))
12685 ipsec_optlen = IPSEC_HDRSIZE(ipv4, inp);
12688#if defined(IPSEC) || defined(IPSEC_SUPPORT)
12689 ipoptlen += ipsec_optlen;
12699 recwin = lmin(lmax(sbspace(&so->so_rcv), 0),
12716 if (len >= p_maxseg)
12779 if (flags & TH_RST) {
12790 if (flags & TH_FIN &&
12798 SOCKBUF_UNLOCK(sb);
12804 if (tot_len == 0) {
12862 if (doing_tlp == 0) {
12880 if (sbused(sb) > 0) {
12885 if (flags & TH_FIN) {
12901 (flags & TH_FIN))) {
12906 SOCKBUF_LOCK_ASSERT(sb);
12921 tp->
t_flags2 &= ~TF2_PLPMTU_MAXSEGSNT;
12933 hdrlen =
sizeof(
struct ip6_hdr) + sizeof(struct tcphdr);
12947 if (flags & TH_SYN) {
12988 local_options += TCPOLEN_TIMESTAMP + 2;
12992 (so->so_rcv.sb_flags & SB_AUTOSIZE))
12995 if (flags & TH_SYN)
13003#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
13022 SOCKBUF_UNLOCK(&so->so_snd);
13023 return (EHOSTUNREACH);
13025 hdrlen +=
sizeof(
struct udphdr);
13029 ipoptlen = ip6_optlen(tp->
t_inpcb);
13034 offsetof(
struct ipoption, ipopt_list);
13038#if defined(IPSEC) || defined(IPSEC_SUPPORT)
13039 ipoptlen += ipsec_optlen;
13048 maxseg = tp->
t_maxseg - (ipoptlen + optlen);
13049 p_maxseg = min(maxseg, pace_max_segs);
13055 if (len > maxseg) {
13056 if (len != 0 && (flags & TH_FIN)) {
13067 KASSERT(ipoptlen == 0,
13068 (
"%s: TSO can't do IP options", __func__));
13074 if (if_hw_tsomax != 0) {
13076 max_len = (if_hw_tsomax - hdrlen -
13078 if (max_len <= 0) {
13080 }
else if (len > max_len) {
13088 if ((sb_offset + len) < sbavail(sb)) {
13098 if (len <= maxseg) {
13104 if (optlen + ipoptlen >= tp->
t_maxseg) {
13113 SOCKBUF_UNLOCK(&so->so_snd);
13122 if_hw_tsomaxsegcount = 0;
13126 (
"%s: len > IP_MAXPACKET", __func__));
13129 if (max_linkhdr + hdrlen > MCLBYTES)
13131 if (max_linkhdr + hdrlen > MHLEN)
13133 panic(
"tcphdr too big");
13140#ifdef BBR_INVARIANTS
13143 panic(
"RSM:%p TP:%p bbr:%p start:%u is < snd_una:%u",
13148 KASSERT(len >= 0, (
"[%s:%d]: len < 0", __func__, __LINE__));
13150 (flags & TH_FIN) &&
13169 if ((rsm == NULL) && len > pace_max_segs)
13170 len = pace_max_segs;
13174 if (MHLEN < hdrlen + max_linkhdr)
13175 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
13178 m = m_gethdr(M_NOWAIT, MT_DATA);
13183 SOCKBUF_UNLOCK(sb);
13188 m->m_data += max_linkhdr;
13194 if ((sb_offset > sbavail(sb)) || ((len + sb_offset) > sbavail(sb))) {
13195#ifdef BBR_INVARIANTS
13196 if ((len + sb_offset) > (sbavail(sb) + ((flags & (TH_FIN | TH_SYN)) ? 1 : 0)))
13197 panic(
"tp:%p bbr:%p len:%u sb_offset:%u sbavail:%u rsm:%p %u:%u:%u",
13198 tp, bbr, len, sb_offset, sbavail(sb), rsm,
13227 SOCKBUF_UNLOCK(sb);
13233 if (len > sbavail(sb))
13238 mb = sbsndptr_noadv(sb, sb_offset, &moff);
13239 if (len <= MHLEN - hdrlen - max_linkhdr && !hw_tls) {
13240 m_copydata(mb, moff, (
int)len,
13241 mtod(m, caddr_t)+hdrlen);
13243 sbsndptr_adv(sb, mb, len);
13246 struct sockbuf *msb;
13252#ifdef BBR_INVARIANTS
13253 if ((len + moff) > (sbavail(sb) + ((flags & (TH_FIN | TH_SYN)) ? 1 : 0))) {
13255 panic(
"tp:%p bbr:%p len:%u moff:%u sbavail:%u rsm:%p snd_una:%u rsm_start:%u flg:%x %u:%u:%u sr:%d ",
13256 tp, bbr, len, moff,
13261 doing_tlp, sack_rxmit);
13263 panic(
"tp:%p bbr:%p len:%u moff:%u sbavail:%u sb_offset:%u snd_una:%u",
13264 tp, bbr, len, moff, sbavail(sb), sb_offset, tp->
snd_una);
13270 if_hw_tsomaxsegcount,
13271 if_hw_tsomaxsegsize, msb,
13272 ((rsm == NULL) ? hw_tls : 0)
13273#ifdef NETFLIX_COPY_ARGS
13277 if (len <= maxseg) {
13286 if (m->m_next == NULL) {
13287 SOCKBUF_UNLOCK(sb);
13294#ifdef BBR_INVARIANTS
13295 if (tso && len < maxseg) {
13296 panic(
"tp:%p tso on, but len:%d < maxseg:%d",
13299 if (tso && if_hw_tsomaxsegcount) {
13300 int32_t seg_cnt = 0;
13308 if (seg_cnt > if_hw_tsomaxsegcount) {
13309 panic(
"seg_cnt:%d > max:%d", seg_cnt, if_hw_tsomaxsegcount);
13318 if (sb_offset + len == sbused(sb) &&
13320 !(flags & TH_SYN)) {
13323 SOCKBUF_UNLOCK(sb);
13325 SOCKBUF_UNLOCK(sb);
13328 else if (flags & (TH_SYN | TH_FIN | TH_RST))
13333 m = m_gethdr(M_NOWAIT, MT_DATA);
13343 if (isipv6 && (MHLEN < hdrlen + max_linkhdr) &&
13345 M_ALIGN(m, hdrlen);
13348 m->m_data += max_linkhdr;
13351 SOCKBUF_UNLOCK_ASSERT(sb);
13352 m->m_pkthdr.rcvif = (
struct ifnet *)0;
13354 mac_inpcb_create_mbuf(inp, m);
13358 ip6 = mtod(m,
struct ip6_hdr *);
13360 udp = (
struct udphdr *)((caddr_t)ip6 +
sizeof(
struct ip6_hdr));
13363 ulen = hdrlen + len -
sizeof(
struct ip6_hdr);
13365 th = (
struct tcphdr *)(udp + 1);
13367 th = (
struct tcphdr *)(ip6 + 1);
13373 ip = mtod(m,
struct ip *);
13378 udp = (
struct udphdr *)((caddr_t)
ip +
sizeof(
struct ip));
13381 ulen = hdrlen + len -
sizeof(
struct ip);
13383 th = (
struct tcphdr *)(udp + 1);
13385 th = (
struct tcphdr *)(
ip + 1);
13400 if (sack_rxmit == 0) {
13401 if (len && ((flags & (TH_FIN | TH_SYN | TH_RST)) == 0)) {
13403 th->th_seq = htonl(tp->
snd_max);
13405 }
else if (flags & TH_SYN) {
13407 th->th_seq = htonl(tp->
iss);
13409 }
else if (flags & TH_FIN) {
13415 th->th_seq = (htonl(tp->
snd_max - 1));
13419 th->th_seq = htonl(tp->
snd_max);
13436 th->th_seq = htonl(tp->
snd_max - 1);
13439 th->th_seq = htonl(tp->
snd_max);
13445 th->th_seq = htonl(rsm->
r_start);
13448 th->th_ack = htonl(tp->
rcv_nxt);
13450 bcopy(opt, th + 1, optlen);
13451 th->th_off = (
sizeof(
struct tcphdr) + optlen) >> 2;
13458 if ((flags & TH_RST) || ((recwin < (so->so_rcv.sb_hiwat / 4) &&
13464 if (recwin > TCP_MAXWIN << tp->
rcv_scale)
13472 if (flags & TH_SYN)
13473 th->th_win = htons((u_short)
13474 (min(sbspace(&so->so_rcv), TCP_MAXWIN)));
13477 recwin = roundup2(recwin, 1 << tp->
rcv_scale);
13478 th->th_win = htons((u_short)(recwin >> tp->
rcv_scale));
13488 if (th->th_win == 0) {
13492 tp->
t_flags &= ~TF_RXWIN0SENT;
13499#if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE)
13506 if (!TCPMD5_ENABLED() || TCPMD5_OUTPUT(m, th,
13521 m->m_pkthdr.len = hdrlen + len;
13529 m->m_pkthdr.csum_flags = CSUM_UDP_IPV6;
13530 m->m_pkthdr.csum_data = offsetof(
struct udphdr, uh_sum);
13532 th->th_sum = htons(0);
13535 csum_flags = m->m_pkthdr.csum_flags = CSUM_TCP_IPV6;
13536 m->m_pkthdr.csum_data = offsetof(
struct tcphdr, th_sum);
13537 th->th_sum = in6_cksum_pseudo(ip6,
sizeof(
struct tcphdr) +
13542#if defined(INET6) && defined(INET)
13548 m->m_pkthdr.csum_flags = CSUM_UDP;
13549 m->m_pkthdr.csum_data = offsetof(
struct udphdr, uh_sum);
13552 th->th_sum = htons(0);
13555 csum_flags = m->m_pkthdr.csum_flags = CSUM_TCP;
13556 m->m_pkthdr.csum_data = offsetof(
struct tcphdr, th_sum);
13563 (
"%s: IP version incorrect: %d", __func__,
ip->
ip_v));
13573 KASSERT(len > maxseg,
13574 (
"%s: len:%d <= tso_segsz:%d", __func__, len, maxseg));
13575 m->m_pkthdr.csum_flags |= CSUM_TSO;
13576 csum_flags |= CSUM_TSO;
13577 m->m_pkthdr.tso_segsz = maxseg;
13579 KASSERT(len + hdrlen == m_length(m, NULL),
13580 (
"%s: mbuf chain different than expected: %d + %u != %u",
13581 __func__, len, hdrlen, m_length(m, NULL)));
13585 hhook_run_tcp_est_out(tp, th, &to, len, tso);
13591 if (so->so_options & SO_DEBUG) {
13599 ipov->
ih_len = htons(m->m_pkthdr.len
13632 if (rsm || sack_rxmit) {
13641 len, &log,
false, NULL, NULL, 0, tv);
13662 ip6->ip6_hlim = in6_selecthlim(inp, NULL);
13669 ip6->ip6_plen = htons(m->m_pkthdr.len -
sizeof(*ip6));
13674 tp->
t_flags2 &= ~TF2_PLPMTU_PMTUD;
13677 TCP_PROBE5(connect__request, NULL, tp, ip6, tp, th);
13686 if (error == EMSGSIZE && inp->
inp_route6.ro_nh != NULL)
13690#if defined(INET) && defined(INET6)
13695 ip->
ip_len = htons(m->m_pkthdr.len);
13698 ip->
ip_ttl = in6_selecthlim(inp, NULL);
13716 tp->
t_flags2 &= ~TF2_PLPMTU_PMTUD;
13727 if (error == EMSGSIZE && inp->
inp_route.ro_nh != NULL)
13754 if ((len > 0) && (rsm == NULL)) {
13765 if (len >= maxseg) {
13766 idx = (len / maxseg) + 3;
13794 cts, mb, &abandon, rsm, 0, sb);
13811 (len || (flags & (TH_SYN | TH_FIN)))) {
13819 if (flags & (TH_SYN | TH_FIN) && (rsm == NULL)) {
13820 if (flags & TH_SYN) {
13832 if (sack_rxmit == 0)
13835 if ((error == 0) && len)
13839 int32_t xlen = len;
13844 if (flags & TH_SYN)
13858 if (sack_rxmit == 0)
13860 tot_len += (len + optlen + ipoptlen);
13871 SOCKBUF_UNLOCK_ASSERT(sb);
13882 return (-ENETDOWN);
13929 if (old_maxseg <= tp->t_maxseg) {
13938 if ((tot_len + len) && (len >= tp->
t_maxseg)) {
13941 (tot_len + len), cts, 0);
13975 min(sbavail(&so->so_snd) - sb_offset, sendwin);
13995 uint64_t rate_wanted;
14010 __LINE__, cts, err);
14031 __LINE__, cts, err);
14045 }
else if ((inp->
inp_route.ro_nh == NULL) ||
14068 if ((error == 0) &&
14070 (doing_tlp == 0) &&
14073 ((flags & TH_RST) == 0) &&
14074 ((flags & TH_SYN) == 0) &&
14097 if ((error == 0) && (flags & TH_FIN))
14099 if ((error == 0) && (flags & TH_RST))
14101 if (((flags & (TH_RST | TH_SYN | TH_FIN)) == 0) && tot_len) {
14154 NET_EPOCH_ASSERT();
14205 if (flags & PRUS_OOB)
14206 return (EOPNOTSUPP);
14239 struct epoch_tracker et;
14242 int32_t error = 0, optval;
14244 switch (sopt->sopt_level) {
14250 switch (sopt->sopt_name) {
14251 case TCP_RACK_PACE_MAX_SEG:
14252 case TCP_RACK_MIN_TO:
14253 case TCP_RACK_REORD_THRESH:
14254 case TCP_RACK_REORD_FADE:
14255 case TCP_RACK_TLP_THRESH:
14256 case TCP_RACK_PKT_DELAY:
14257 case TCP_BBR_ALGORITHM:
14258 case TCP_BBR_TSLIMITS:
14259 case TCP_BBR_IWINTSO:
14260 case TCP_BBR_RECFORCE:
14261 case TCP_BBR_STARTUP_PG:
14262 case TCP_BBR_DRAIN_PG:
14263 case TCP_BBR_RWND_IS_APP:
14264 case TCP_BBR_PROBE_RTT_INT:
14265 case TCP_BBR_PROBE_RTT_GAIN:
14266 case TCP_BBR_PROBE_RTT_LEN:
14267 case TCP_BBR_STARTUP_LOSS_EXIT:
14268 case TCP_BBR_USEDEL_RATE:
14269 case TCP_BBR_MIN_RTO:
14270 case TCP_BBR_MAX_RTO:
14271 case TCP_BBR_PACE_PER_SEC:
14273 case TCP_BBR_PACE_DEL_TAR:
14274 case TCP_BBR_SEND_IWND_IN_TSO:
14275 case TCP_BBR_EXTRA_STATE:
14276 case TCP_BBR_UTTER_MAX_TSO:
14277 case TCP_BBR_MIN_TOPACEOUT:
14278 case TCP_BBR_FLOOR_MIN_TSO:
14279 case TCP_BBR_TSTMP_RAISES:
14280 case TCP_BBR_POLICER_DETECT:
14281 case TCP_BBR_USE_RACK_CHEAT:
14282 case TCP_DATA_AFTER_CLOSE:
14283 case TCP_BBR_HDWR_PACE:
14284 case TCP_BBR_PACE_SEG_MAX:
14285 case TCP_BBR_PACE_SEG_MIN:
14286 case TCP_BBR_PACE_CROSS:
14287 case TCP_BBR_PACE_OH:
14288#ifdef NETFLIX_PEAKRATE
14289 case TCP_MAXPEAKRATE:
14291 case TCP_BBR_TMR_PACE_OH:
14292 case TCP_BBR_RACK_RTT_USE:
14293 case TCP_BBR_RETRAN_WTSO:
14300 error = sooptcopyin(sopt, &optval,
sizeof(optval),
sizeof(optval));
14306 return (ECONNRESET);
14311 return (ENOPROTOOPT);
14314 switch (sopt->sopt_name) {
14315 case TCP_BBR_PACE_PER_SEC:
14319 case TCP_BBR_PACE_DEL_TAR:
14323 case TCP_BBR_PACE_SEG_MAX:
14327 case TCP_BBR_PACE_SEG_MIN:
14331 case TCP_BBR_PACE_CROSS:
14335 case TCP_BBR_ALGORITHM:
14340 if ((optval > 3) && (optval < 500)) {
14352 case TCP_BBR_TSLIMITS:
14356 else if (optval == 0)
14362 case TCP_BBR_IWINTSO:
14364 if ((optval >= 0) && (optval < 128)) {
14376 case TCP_BBR_STARTUP_PG:
14386 case TCP_BBR_DRAIN_PG:
14393 case TCP_BBR_PROBE_RTT_LEN:
14400 case TCP_BBR_PROBE_RTT_GAIN:
14407 case TCP_BBR_PROBE_RTT_INT:
14414 case TCP_BBR_MIN_TOPACEOUT:
14419 }
else if (optval <= 0x00ff) {
14429 case TCP_BBR_STARTUP_LOSS_EXIT:
14433 case TCP_BBR_USEDEL_RATE:
14436 case TCP_BBR_MIN_RTO:
14440 case TCP_BBR_MAX_RTO:
14444 case TCP_RACK_MIN_TO:
14449 case TCP_RACK_REORD_THRESH:
14452 if ((optval > 0) && (optval < 31))
14457 case TCP_RACK_REORD_FADE:
14462 case TCP_RACK_TLP_THRESH:
14470 case TCP_BBR_USE_RACK_CHEAT:
14482 case TCP_BBR_FLOOR_MIN_TSO:
14484 if ((optval >= 0) && (optval < 40))
14489 case TCP_BBR_UTTER_MAX_TSO:
14491 if ((optval >= 0) && (optval < 0xffff))
14497 case TCP_BBR_EXTRA_STATE:
14504 case TCP_BBR_SEND_IWND_IN_TSO:
14516 case TCP_BBR_HDWR_PACE:
14534 if (optval < 100) {
14537 else if (optval == 1)
14544 NET_EPOCH_ENTER(et);
14546 NET_EPOCH_EXIT(et);
14551 case TCP_RACK_PKT_DELAY:
14556#ifdef NETFLIX_PEAKRATE
14557 case TCP_MAXPEAKRATE:
14559 error = tcp_set_maxpeakrate(tp, optval);
14564 case TCP_BBR_RETRAN_WTSO:
14571 case TCP_DATA_AFTER_CLOSE:
14578 case TCP_BBR_POLICER_DETECT:
14588 case TCP_BBR_TSTMP_RAISES:
14595 case TCP_BBR_TMR_PACE_OH:
14606 case TCP_BBR_PACE_OH:
14635#ifdef NETFLIX_STATS
14636 tcp_log_socket_option(tp, sopt->sopt_name, optval, error);
14650 int32_t error, optval;
14664 switch (sopt->sopt_name) {
14665 case TCP_BBR_PACE_PER_SEC:
14668 case TCP_BBR_PACE_DEL_TAR:
14671 case TCP_BBR_PACE_SEG_MAX:
14674 case TCP_BBR_MIN_TOPACEOUT:
14677 case TCP_BBR_PACE_SEG_MIN:
14680 case TCP_BBR_PACE_CROSS:
14683 case TCP_BBR_ALGORITHM:
14686 case TCP_BBR_TSLIMITS:
14689 case TCP_BBR_IWINTSO:
14692 case TCP_BBR_STARTUP_PG:
14695 case TCP_BBR_DRAIN_PG:
14698 case TCP_BBR_PROBE_RTT_INT:
14701 case TCP_BBR_PROBE_RTT_LEN:
14704 case TCP_BBR_PROBE_RTT_GAIN:
14707 case TCP_BBR_STARTUP_LOSS_EXIT:
14710 case TCP_BBR_USEDEL_RATE:
14713 case TCP_BBR_MIN_RTO:
14716 case TCP_BBR_MAX_RTO:
14719 case TCP_RACK_PACE_MAX_SEG:
14723 case TCP_RACK_MIN_TO:
14727 case TCP_RACK_REORD_THRESH:
14731 case TCP_RACK_REORD_FADE:
14735 case TCP_BBR_USE_RACK_CHEAT:
14739 case TCP_BBR_FLOOR_MIN_TSO:
14742 case TCP_BBR_UTTER_MAX_TSO:
14745 case TCP_BBR_SEND_IWND_IN_TSO:
14749 case TCP_BBR_EXTRA_STATE:
14752 case TCP_RACK_TLP_THRESH:
14756 case TCP_RACK_PKT_DELAY:
14760 case TCP_BBR_RETRAN_WTSO:
14763 case TCP_DATA_AFTER_CLOSE:
14769 case TCP_BBR_HDWR_PACE:
14772 case TCP_BBR_POLICER_DETECT:
14775 case TCP_BBR_TSTMP_RAISES:
14778 case TCP_BBR_TMR_PACE_OH:
14781 case TCP_BBR_PACE_OH:
14795 error = sooptcopyout(sopt, &optval,
sizeof optval);
14805 if (sopt->sopt_dir == SOPT_SET) {
14807 }
else if (sopt->sopt_dir == SOPT_GET) {
14810 panic(
"%s: sopt_dir $%d", __func__, sopt->sopt_dir);
14815 __XSTRING(STACKNAME),
14817 __XSTRING(STACKALIAS),
14831 printf(
"Attempting to load " __XSTRING(MODNAME)
"\n");
14832 bbr_zone = uma_zcreate(__XSTRING(MODNAME)
"_map",
14834 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
14837 NULL, NULL, NULL, NULL, UMA_ALIGN_CACHE, 0);
14840 SYSCTL_STATIC_CHILDREN(_net_inet_tcp),
14843 __XSTRING(STACKALIAS),
14845 __XSTRING(STACKNAME),
14847 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
14850 printf(
"Failed to add sysctl node\n");
14859 printf(
"Failed to register %s stack name for "
14861 __XSTRING(MODNAME));
14867 printf(
"Failed to register " __XSTRING(MODNAME)
14868 " module err:%d\n", err);
14873 printf(__XSTRING(MODNAME)
" is now available\n");
14887 printf(__XSTRING(MODNAME)
14888 " is now no longer available\n");
14895 return (EOPNOTSUPP);
14901 .name = __XSTRING(MODNAME),
static uint32_t bbr_calc_time(uint32_t cts, uint32_t earlier_time)
static void tcp_bbr_xmit_timer_commit(struct tcp_bbr *bbr, struct tcpcb *tp, uint32_t cts)
static void bbr_timer_activate(struct tcpcb *tp, uint32_t timer_type, uint32_t delta)
static uint32_t bbr_what_can_we_send(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t sendwin, uint32_t avail, int32_t sb_offset, uint32_t cts)
static void bbr_timer_stop(struct tcpcb *tp, uint32_t timer_type)
static void tcp_bbr_xmit_timer(struct tcp_bbr *bbr, uint32_t rtt_usecs, uint32_t rsm_send_time, uint32_t r_start, uint32_t tsin)
static int bbr_do_syn_recv(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos)
static int32_t bbr_hptsi_utter_max
static int32_t bbr_hptsi_segments_delay_tar
static int bbr_handoff_ok(struct tcpcb *tp)
static int32_t bbr_include_tcp_oh
static void bbr_un_collapse_window(struct tcp_bbr *bbr)
static uint32_t bbr_calc_thresh_rack(struct tcp_bbr *bbr, uint32_t srtt, uint32_t cts, struct bbr_sendmap *rsm)
static uint32_t bbr_get_earliest_send_outstanding(struct tcp_bbr *bbr, struct bbr_sendmap *u_rsm, uint32_t cts)
counter_u64_t bbr_stat_arry[BBR_STAT_SIZE]
static int32_t bbr_reorder_thresh
static void bbr_log_enobuf_jmp(struct tcp_bbr *bbr, uint32_t len, uint32_t cts, int32_t line, uint32_t o_len, uint32_t segcnt, uint32_t segsiz)
static int32_t bbr_persist_max
static int32_t bbr_startup_loss_thresh
static void bbr_type_log_hdwr_pacing(struct tcp_bbr *bbr, const struct ifnet *ifp, uint64_t rate, uint64_t hw_rate, int line, uint32_t cts, int error)
static struct bbr_sendmap * bbr_alloc_full_limit(struct tcp_bbr *bbr)
static void bbr_start_hpts_timer(struct tcp_bbr *bbr, struct tcpcb *tp, uint32_t cts, int32_t frm, int32_t slot, uint32_t tot_len)
static int32_t bbr_resends_use_tso
#define DELAY_ACK(tp, bbr, nsegs)
static void bbr_update_bbr_info(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t rtt, uint32_t cts, uint32_t tsin, uint32_t uts, int32_t match, uint32_t rsm_send_time, int32_t ack_type, struct tcpopt *to)
static int bbr_do_close_wait(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos)
static uint32_t get_min_cwnd(struct tcp_bbr *bbr)
static int32_t bbr_hptsi_segments_floor
int32_t bbr_sends_full_iwnd
static int32_t bbr_target_is_bbunit
static int32_t bbr_initial_bw_bps
static int bbr_window_update_needed(struct tcpcb *tp, struct socket *so, uint32_t recwin, int32_t maxseg)
static int32_t bbr_cwnd_min_val_hs
static __inline void bbr_clone_rsm(struct tcp_bbr *bbr, struct bbr_sendmap *nrsm, struct bbr_sendmap *rsm, uint32_t start)
static __inline void bbr_fill_in_logging_data(struct tcp_bbr *bbr, struct tcp_log_bbr *l, uint32_t cts)
static uint64_t bbr_get_bw(struct tcp_bbr *bbr)
static void bbr_post_recovery(struct tcpcb *tp)
static int16_t bbr_hptsi_gain[]
static uint32_t bbr_get_raw_target_cwnd(struct tcp_bbr *bbr, uint32_t gain, uint64_t bw)
static void bbr_cwnd_limiting(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t in_level)
static void bbr_log_type_bbrrttprop(struct tcp_bbr *bbr, uint32_t t, uint32_t end, uint32_t tsconv, uint32_t cts, int32_t match, uint32_t seq, uint8_t flags)
static void bbr_set_state_target(struct tcp_bbr *bbr, int line)
static int32_t bbr_ts_can_raise
static int32_t bbr_gain_gets_extra_too
static void bbr_log_hpts_diag(struct tcp_bbr *bbr, uint32_t cts, struct hpts_diag *diag)
static uint8_t bbr_pick_probebw_substate(struct tcp_bbr *bbr, uint32_t cts)
static int32_t bbr_max_net_error_cnt
static uint32_t bbr_lt_bw_max_rtts
static void bbr_log_type_ltbw(struct tcp_bbr *bbr, uint32_t cts, int32_t reason, uint32_t newbw, uint32_t obw, uint32_t diff, uint32_t tim)
static int bbr_do_fin_wait_2(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos)
static int bbr_process_ack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, uint32_t tiwin, int32_t tlen, int32_t *ofia, int32_t thflags, int32_t *ret_val)
static int bbr_init(struct tcpcb *tp)
static void bbr_state_change(struct tcp_bbr *bbr, uint32_t cts, int32_t epoch, int32_t pkt_epoch, uint32_t losses)
static int32_t bbr_no_pacing_until
static void bbr_log_pkt_epoch(struct tcp_bbr *bbr, uint32_t cts, uint32_t line, uint32_t lost, uint32_t del)
static int32_t bbr_should_enter_probe_rtt(struct tcp_bbr *bbr, uint32_t cts)
static void bbr_log_type_rsmclear(struct tcp_bbr *bbr, uint32_t cts, struct bbr_sendmap *rsm, uint32_t flags, uint32_t line)
counter_u64_t bbr_state_lost[BBR_MAX_STAT]
static const char * bbr_stack_names[]
static int bbr_do_syn_sent(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos)
static int32_t bbr_hptsi_max_mul
static void bbr_log_to_event(struct tcp_bbr *bbr, uint32_t cts, int32_t to_num)
static int32_t bbr_drain_floor
static uint32_t bbr_lt_intvl_min_rtts
static void bbr_collapsed_window(struct tcp_bbr *bbr)
static void bbr_strike_dupack(struct tcp_bbr *bbr)
static uint32_t bbr_get_pacing_length(struct tcp_bbr *bbr, uint16_t gain, uint32_t useconds_time, uint64_t bw)
static int32_t bbr_can_force_probertt
struct sysctl_oid * bbr_sysctl_root
static void bbr_log_flowend(struct tcp_bbr *bbr)
static int bbr_timeout_delack(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
static uint64_t bbr_get_hardware_rate(struct tcp_bbr *bbr)
static int32_t bbr_can_use_ts_for_rtt
static void bbr_isit_a_pkt_epoch(struct tcp_bbr *bbr, uint32_t cts, struct bbr_sendmap *rsm, int32_t line, int32_t cum_acked)
static void bbr_reset_lt_bw_interval(struct tcp_bbr *bbr, uint32_t cts)
static void bbr_log_exit_gain(struct tcp_bbr *bbr, uint32_t cts, int32_t entry_method)
static int32_t bbr_rto_max_sec
static int bbr_sack_mergable(struct bbr_sendmap *at, uint32_t start, uint32_t end)
counter_u64_t bbr_flows_nohdwr_pacing
static void bbr_log_timer_var(struct tcp_bbr *bbr, int mode, uint32_t cts, uint32_t time_since_sent, uint32_t srtt, uint32_t thresh, uint32_t to)
static int32_t bbr_cwnd_may_shrink
static int32_t bbr_policer_detection_enabled
static int32_t bbr_use_lower_gain_in_startup
counter_u64_t bbr_flows_whdwr_pacing
static int sysctl_bbr_clear_lost(SYSCTL_HANDLER_ARGS)
static void bbr_log_type_enter_rec(struct tcp_bbr *bbr, uint32_t seq)
static void bbr_update_rsm(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t cts, uint32_t pacing_time)
static int32_t bbr_idle_restart_threshold
static void bbr_check_probe_rtt_limits(struct tcp_bbr *bbr, uint32_t cts)
static void bbr_set_probebw_gains(struct tcp_bbr *bbr, uint32_t cts, uint32_t losses)
static int32_t bbr_persist_min
static int32_t bbr_slam_cwnd_in_main_drain
static void bbr_setup_less_of_rate(struct tcp_bbr *bbr, uint32_t cts, uint64_t act_rate, uint64_t rate_wanted)
static int32_t bbr_hdwr_pace_adjust
static int32_t bbr_red_scale
static int bbr_output(struct tcpcb *tp)
static uint32_t bbr_cross_over
static int32_t bbr_red_mul
counter_u64_t bbr_opts_arry[BBR_OPTS_SIZE]
static int32_t bbr_cwnd_gain
static int32_t bbr_hptsi_segments_max
static void bbr_lt_bw_sampling(struct tcp_bbr *bbr, uint32_t cts, int32_t loss_detected)
static int32_t bbr_gain_to_target
static int bbr_get_sockopt(struct inpcb *inp, struct sockopt *sopt)
static __inline uint32_t bbr_get_rtt(struct tcp_bbr *bbr, int32_t rtt_type)
counter_u64_t bbr_state_resend[BBR_MAX_STAT]
static void bbr_log_ack_clear(struct tcp_bbr *bbr, uint32_t cts)
static int bbr_do_fastnewdata(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t nxt_pkt)
static int bbr_ctloutput(struct inpcb *inp, struct sockopt *sopt)
static void bbr_log_startup_event(struct tcp_bbr *bbr, uint32_t cts, uint32_t flex1, uint32_t flex2, uint32_t flex3, uint8_t reason)
static int32_t bbr_hdwr_pace_floor
static int32_t bbr_include_enet_oh
static int32_t bbr_verbose_logging
static int32_t bbr_num_pktepo_for_del_limit
static int32_t bbr_sack_not_required
static int bbr_timeout_keepalive(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
static bool bbr_mod_inited
DECLARE_MODULE(MODNAME, tcp_bbr, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY)
MODULE_DEPEND(MODNAME, tcphpts, 1, 1, 1)
static uint64_t bbr_lt_bw_ratio
static int32_t bbr_target_cwnd_mult_limit
static int32_t bbr_drain_drop_div
static void bbr_set_pktepoch(struct tcp_bbr *bbr, uint32_t cts, int32_t line)
static void bbr_log_rtt_sample(struct tcp_bbr *bbr, uint32_t rtt, uint32_t tsin)
static void bbr_log_sack_passed(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm)
#define TCPT_RANGESET_NOSLOP(tv, value, tvmin, tvmax)
static int bbr_timer_active(struct tcpcb *tp, uint32_t timer_type)
static int32_t bbr_delayed_ack_time
static int32_t bbr_hptsi_per_second
static int32_t bbr_google_startup(struct tcp_bbr *bbr, uint32_t cts, int32_t pkt_epoch)
static int32_t bbr_include_ip_oh
static int32_t bbr_exit_startup_at_loss
static int32_t bbr_filter_len_sec
static void bbr_log_doseg_done(struct tcp_bbr *bbr, uint32_t cts, int32_t nxt_pkt, int32_t did_out)
static void bbr_log_type_tsosize(struct tcp_bbr *bbr, uint32_t cts, uint32_t tsosz, uint32_t tls, uint32_t old_val, uint32_t maxseg, int hdwr)
static void bbr_init_sysctls(void)
static void bbr_google_measurement(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t rtt, uint32_t cts)
static int bbr_is_lost(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t cts)
static void bbr_log_type_bw_reduce(struct tcp_bbr *bbr, int reason)
struct sysctl_ctx_list bbr_sysctl_ctx
counter_u64_t bbr_nohdwr_pacing_enobuf
static uint32_t bbr_calc_thresh_tlp(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t srtt, uint32_t cts)
static void bbr_google_mode_on(struct tcp_bbr *bbr)
static int32_t bbr_tlp_min
static uint64_t bbr_lt_bw_diff
static void tcp_bbr_tso_size_check(struct tcp_bbr *bbr, uint32_t cts)
static int32_t bbr_reorder_fade
MODULE_VERSION(MODNAME, 1)
static void bbr_peer_reneges(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, tcp_seq th_ack)
static int32_t bbr_tlp_max_resend
static int32_t bbr_sub_drain_app_limit
static int bbr_fastack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t nxt_pkt, uint8_t iptos)
static int bbr_do_lastack(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos)
static void bbr_log_to_processing(struct tcp_bbr *bbr, uint32_t cts, int32_t ret, int32_t timers, uint8_t hpts_calling)
static void bbr_set_probebw_google_gains(struct tcp_bbr *bbr, uint32_t cts, uint32_t losses)
static int32_t bbr_state_drain_2_tar
static uint8_t bbr_state_val(struct tcp_bbr *bbr)
static int32_t bbr_hardware_pacing_limit
static int32_t bbr_drain_drop_mul
struct tcp_function_block __tcp_bbr
static void bbr_log_type_rwnd_collapse(struct tcp_bbr *bbr, int seq, int mode, uint32_t count)
static void bbr_timer_cancel(struct tcp_bbr *bbr, int32_t line, uint32_t cts)
static int32_t bbr_pkt_delay
static void bbr_log_ack_event(struct tcp_bbr *bbr, struct tcphdr *th, struct tcpopt *to, uint32_t tlen, uint16_t nsegs, uint32_t cts, int32_t nxt_pkt, struct mbuf *m)
static uint16_t bbr_gain_adjust(struct tcp_bbr *bbr, uint16_t gain)
static void bbr_log_to_cancel(struct tcp_bbr *bbr, int32_t line, uint32_t cts, uint8_t hpts_removed)
static int32_t bbr_lt_loss_thresh
static int32_t bbr_drain_rtt
static int32_t bbr_ignore_data_after_close
static void bbr_set_epoch(struct tcp_bbr *bbr, uint32_t cts, int32_t line)
static void bbr_mtu_chg(struct tcpcb *tp)
static void bbr_setup_red_bw(struct tcp_bbr *bbr, uint32_t cts)
static int32_t bbr_cwndtarget_rtt_touse
static uint64_t __bbr_get_bw(struct tcp_bbr *bbr)
static uint32_t bbr_get_target_cwnd(struct tcp_bbr *bbr, uint64_t bw, uint32_t gain)
static void bbr_log_msgsize_fail(struct tcp_bbr *bbr, struct tcpcb *tp, uint32_t len, uint32_t maxseg, uint32_t mtu, int32_t csum_flags, int32_t tso, uint32_t cts)
static void bbr_nf_measurement(struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t rtt, uint32_t cts)
static void bbr_set_reduced_rtt(struct tcp_bbr *bbr, uint32_t cts, uint32_t line)
static void bbr_substate_change(struct tcp_bbr *bbr, uint32_t cts, int line, int dolog)
static void bbr_make_timestamp_determination(struct tcp_bbr *bbr)
static void bbr_lt_bw_samp_done(struct tcp_bbr *bbr, uint64_t bw, uint32_t cts, uint32_t timin)
static void bbr_enter_probe_rtt(struct tcp_bbr *bbr, uint32_t cts, int32_t line)
static int32_t bbr_red_growth_restrict
static void bbr_do_send_accounting(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, int32_t len, int32_t error)
counter_u64_t bbr_hdwr_pacing_enobuf
static int32_t bbr_no_retran
static void bbr_log_set_of_state_target(struct tcp_bbr *bbr, uint32_t new_tar, int line, int meth)
static int32_t bbr_sack_block_limit
static void bbr_set_state(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t win)
static uint32_t bbr_get_header_oh(struct tcp_bbr *bbr)
static void bbr_reset_lt_bw_sampling(struct tcp_bbr *bbr, uint32_t cts)
static void bbr_update_hardware_pacing_rate(struct tcp_bbr *bbr, uint32_t cts)
static int32_t bbr_state_startup(struct tcp_bbr *bbr, uint32_t cts, int32_t epoch, int32_t pkt_epoch)
static void bbr_log_progress_event(struct tcp_bbr *bbr, struct tcpcb *tp, uint32_t tick, int event, int line)
static int32_t bbr_start_exit
static int32_t bbr_all_get_min
static int32_t bbr_min_usec_delta
static uint32_t bbr_rtt_probe_limit
static int32_t bbr_min_to
static void bbr_do_error_accounting(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, int32_t len, int32_t error)
static int32_t bbr_rand_ot
static int32_t bbr_google_discount
static void bbr_randomize_extra_state_time(struct tcp_bbr *bbr)
static int bbr_do_closing(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos)
static void bbr_fini(struct tcpcb *tp, int32_t tcb_is_purged)
static void bbr_adjust_for_hw_pacing(struct tcp_bbr *bbr, uint32_t cts)
static int32_t google_consider_lost
static void bbr_log_syn(struct tcpcb *tp, struct tcpopt *to)
static int32_t bbr_is_ratio
static int32_t bbr_ts_limiting
static uint32_t bbr_proc_sack_blk(struct tcpcb *tp, struct tcp_bbr *bbr, struct sackblk *sack, struct tcpopt *to, struct bbr_sendmap **prsm, uint32_t cts)
static uint32_t bbr_get_pacing_delay(struct tcp_bbr *bbr, uint16_t gain, int32_t len, uint32_t cts, int nolog)
static int32_t bbr_min_measurements_req
static void bbr_free(struct tcp_bbr *bbr, struct bbr_sendmap *rsm)
static struct bbr_sendmap * bbr_find_high_nonack(struct tcp_bbr *bbr, struct bbr_sendmap *rsm)
static int32_t bbr_low_start_exit
static int32_t bbr_sub_drain_slam_cwnd
static void bbr_log_rtt_shrinks(struct tcp_bbr *bbr, uint32_t cts, uint32_t applied, uint32_t rtt, uint32_t line, uint8_t is_start, uint16_t set)
counter_u64_t bbr_out_size[TCP_MSS_ACCT_SIZE]
static int32_t bbr_do_red
static int32_t bbr_drop_limit
static int32_t bbr_state_is_pkt_epoch
static int32_t bbr_red_div
static int32_t bbr_high_gain
static int32_t bbr_error_base_paceout
static int32_t bbr_hdwr_pacing_delay_cnt
static void bbr_counter_destroy(void)
counter_u64_t bbr_state_time[BBR_MAX_STAT]
static void bbr_log_to_start(struct tcp_bbr *bbr, uint32_t cts, uint32_t to, int32_t slot, uint8_t which)
static int32_t bbr_rttprobe_gain
static void bbr_timer_audit(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, struct sockbuf *sb)
static int32_t bbr_use_google_algo
static void bbr_google_mode_off(struct tcp_bbr *bbr)
static void bbr_log_type_cwndupd(struct tcp_bbr *bbr, uint32_t bytes_this_ack, uint32_t chg, uint32_t prev_acked, int32_t meth, uint32_t target, uint32_t th_ack, int32_t line)
static int32_t bbr_lt_intvl_fp
static uint32_t bbr_timer_start(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
static uint32_t bbr_update_entry(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, uint32_t cts, int32_t *lenp, uint32_t pacing_time)
static int bbr_timeout_tlp(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
static int32_t bbr_can_adjust_probertt
static int bbr_do_fin_wait_1(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos)
static int bbr_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint8_t iptos, int32_t nxt_pkt, struct timeval *tv)
static int32_t bbr_allow_hdwr_pacing
static void bbr_restart_after_idle(struct tcp_bbr *bbr, uint32_t cts, uint32_t idle_time)
static int bbr_timeout_rack(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
static void bbr_check_bbr_for_state(struct tcp_bbr *bbr, uint32_t cts, int32_t line, uint32_t losses)
static uint32_t bbr_rtt_probe_cwndtarg
static void bbr_log_pacing_delay_calc(struct tcp_bbr *bbr, uint16_t gain, uint32_t len, uint32_t cts, uint32_t usecs, uint64_t bw, uint32_t override, int mod)
static void bbr_log_type_pesist(struct tcp_bbr *bbr, uint32_t cts, uint32_t time_in, int32_t line, uint8_t enter_exit)
static int32_t bbr_marks_rxt_sack_passed
static void bbr_stop_all_timers(struct tcpcb *tp)
static void bbr_exit_probe_rtt(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
static int32_t bbr_lt_fd_thresh
static void bbr_log_type_statechange(struct tcp_bbr *bbr, uint32_t cts, int32_t line)
static void bbr_log_thresh_choice(struct tcp_bbr *bbr, uint32_t cts, uint32_t thresh, uint32_t lro, uint32_t srtt, struct bbr_sendmap *rsm, uint8_t frm)
static uint32_t bbr_log_ack(struct tcpcb *tp, struct tcpopt *to, struct tcphdr *th, uint32_t *prev_acked)
static void bbr_log_type_exit_rec(struct tcp_bbr *bbr)
static int bbr_timeout_persist(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
static void bbr_collapse_rtt(struct tcpcb *tp, struct tcp_bbr *bbr, int32_t rtt)
static void bbr_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint8_t iptos)
static int tcp_addbbr(module_t mod, int32_t type, void *data)
static int bbr_update_rtt(struct tcpcb *tp, struct tcp_bbr *bbr, struct bbr_sendmap *rsm, struct tcpopt *to, uint32_t cts, int32_t ack_type, uint32_t th_ack)
static uint32_t bbr_get_persists_timer_val(struct tcpcb *tp, struct tcp_bbr *bbr)
static void bbr_ack_received(struct tcpcb *tp, struct tcp_bbr *bbr, struct tcphdr *th, uint32_t bytes_this_ack, uint32_t sack_changed, uint32_t prev_acked, int32_t line, uint32_t losses)
static int32_t bbr_probertt_sets_rtt
static struct bbr_sendmap * bbr_alloc(struct tcp_bbr *bbr)
static uint64_t bbr_get_bw_delay_prod(uint64_t rtt, uint64_t bw)
static uint64_t bbr_get_full_bw(struct tcp_bbr *bbr)
static void bbr_log_output(struct tcp_bbr *bbr, struct tcpcb *tp, struct tcpopt *to, int32_t len, uint32_t seq_out, uint16_t th_flags, int32_t err, uint32_t cts, struct mbuf *mb, int32_t *abandon, struct bbr_sendmap *hintrsm, uint32_t delay_calc, struct sockbuf *sb)
static void bbr_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type, struct bbr_sendmap *rsm)
static uint32_t bbr_def_init_win
static void bbr_log_settings_change(struct tcp_bbr *bbr, int settings_desired)
static int32_t bbr_drain_gain
static void bbr_log_time_epoch(struct tcp_bbr *bbr, uint32_t cts, uint32_t line, uint32_t epoch_time)
static void tcp_bbr_commit_bw(struct tcp_bbr *bbr, uint32_t cts)
static int bbr_pru_options(struct tcpcb *tp, int flags)
static int32_t bbr_rto_min_ms
static void bbr_log_type_bbrsnd(struct tcp_bbr *bbr, uint32_t len, uint32_t slot, uint32_t del_by, uint32_t cts, uint32_t sloton, uint32_t prev_delay)
static int32_t bbr_rtt_gain_thresh
int32_t bbr_use_rack_resend_cheat
static struct bbr_sendmap * bbr_find_lowest_rsm(struct tcp_bbr *bbr)
static void bbr_log_tstmp_validation(struct tcp_bbr *bbr, uint64_t peer_delta, uint64_t delta)
static int32_t bbr_minseg(struct tcp_bbr *bbr)
static int32_t bbr_delack_time
static uint32_t bbr_rtt_probe_time
static void tcp_bbr_partialack(struct tcpcb *tp)
static uint32_t bbr_initial_cwnd(struct tcp_bbr *bbr, struct tcpcb *tp)
static void bbr_log_type_just_return(struct tcp_bbr *bbr, uint32_t cts, uint32_t tlen, uint8_t hpts_calling, uint8_t reason, uint32_t p_maxseg, int len)
static int32_t bbr_prtt_slam_cwnd
static struct bbr_sendmap * bbr_check_recovery_mode(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
static int32_t bbr_quanta
static int32_t bbr_incr_timers
static uint32_t bbr_get_a_state_target(struct tcp_bbr *bbr, uint32_t gain)
static int32_t bbr_hptsi_bytes_min
static struct bbr_sendmap * bbr_merge_rsm(struct tcp_bbr *bbr, struct bbr_sendmap *l_rsm, struct bbr_sendmap *r_rsm)
static uint32_t bbr_ts_convert(uint32_t cts)
static int32_t bbr_cwnd_min_val
static int32_t bbr_tlp_thresh
static int32_t bbr_policer_call_from_rack_to
static int32_t bbr_min_peer_delta
static int32_t bbr_tlp_type_to_use
static int bbr_set_sockopt(struct inpcb *inp, struct sockopt *sopt)
static int bbr_output_wtime(struct tcpcb *tp, const struct timeval *tv)
static int bbr_process_timers(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, uint8_t hpts_calling)
static void bbr_remxt_tmr(struct tcpcb *tp)
static int bbr_timeout_rxt(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts)
static int32_t bbr_hptsi_max_div
static void bbr_log_type_bbrupd(struct tcp_bbr *bbr, uint8_t flex8, uint32_t cts, uint32_t flex3, uint32_t flex2, uint32_t flex5, uint32_t flex6, uint32_t pkts_out, int flex7, uint32_t flex4, uint32_t flex1)
static int32_t bbr_delta_percent
static int32_t bbr_uses_idle_restart
static int bbr_check_data_after_close(struct mbuf *m, struct tcp_bbr *bbr, struct tcpcb *tp, int32_t *tlen, struct tcphdr *th, struct socket *so)
static int32_t bbr_startup_lower
static int bbr_stopall(struct tcpcb *tp)
static const int32_t bbr_min_req_free
static int bbr_do_established(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, struct tcpopt *to, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt, uint8_t iptos)
static struct bbr_sendmap * bbr_alloc_limit(struct tcp_bbr *bbr, uint8_t limit_type)
static int bbr_process_data(struct mbuf *m, struct tcphdr *th, struct socket *so, struct tcpcb *tp, int32_t drop_hdrlen, int32_t tlen, uint32_t tiwin, int32_t thflags, int32_t nxt_pkt)
static void bbr_exit_persist(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, int32_t line)
static int32_t google_allow_early_out
static void bbr_enter_persist(struct tcpcb *tp, struct tcp_bbr *bbr, uint32_t cts, int32_t line)
#define BANDLIM_UNLIMITED
#define BANDLIM_RST_OPENPORT
u_short in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c)
#define TCP_PROBE5(probe, arg0, arg1, arg2, arg3, arg4)
void in_losing(struct inpcb *inp)
#define INP_DONT_SACK_QUEUE
#define INP_MBUF_QUEUE_READY
#define INP_WLOCK_ASSERT(inp)
#define INP_SUPPORTS_MBUFQ
#define INP_CANNOT_DO_ECN
int ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, struct ip_moptions *imo, struct inpcb *inp)
int32_t ctf_progress_timeout_check(struct tcpcb *tp, bool log)
int ctf_do_queued_segments(struct socket *so, struct tcpcb *tp, int have_pkt)
void ctf_log_sack_filter(struct tcpcb *tp, int num_sack_blks, struct sackblk *sack_blocks)
void ctf_do_dropwithreset(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t rstreason, int32_t tlen)
void ctf_do_drop(struct mbuf *m, struct tcpcb *tp)
void ctf_challenge_ack(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int32_t *ret_val)
uint32_t ctf_outstanding(struct tcpcb *tp)
uint32_t ctf_flight_size(struct tcpcb *tp, uint32_t rc_sacked)
int ctf_ts_check(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, int32_t tlen, int32_t thflags, int32_t *ret_val)
void ctf_calc_rwin(struct socket *so, struct tcpcb *tp)
void ctf_do_dropwithreset_conn(struct mbuf *m, struct tcpcb *tp, struct tcphdr *th, int32_t rstreason, int32_t tlen)
#define TWENTY_THREE_MBPS
#define ctf_drop_checks(a, b, c, d, e, f, g, h)
#define TCP_MSS_SMALL_SIZE_OFF
#define ONE_POINT_TWO_MEG
#define ctf_process_rst(m, t, s, p)
#define BBR_JR_RWND_LIMITED
#define TCP_MSS_ACCT_SIZE
#define TCP_MSS_ACCT_INPACE
#define TCP_MSS_ACCT_JUSTRET
#define BBR_JR_CWND_LIMITED
#define ctf_do_dropafterack(a, b, c, d, e, f)
#define TCP_MSS_ACCT_LATE
#define TCP_MSS_ACCT_SNDACK
#define BBR_JR_APP_LIMITED
#define TCP_MSS_ACCT_ATIMER
#define TCP_MSS_SMALL_MAX_SIZE_DIV
#define PACE_MAX_IP_BYTES
#define DUP_ACK_THRESHOLD
int sack_filter_blks(struct sack_filter *sf, struct sackblk *in, int numblks, tcp_seq th_ack)
void sack_filter_reject(struct sack_filter *sf, struct sackblk *in)
void sack_filter_clear(struct sack_filter *sf, tcp_seq seq)
const struct tcp_hwrate_limit_table * crte
uint16_t rc_num_small_maps_alloced
uint32_t last_startup_measure
uint32_t rc_flight_at_input
uint64_t rc_bbr_lastbtlbw
uint16_t bbr_hptsi_bytes_min
uint32_t rc_pkt_epoch_time
uint32_t rc_bbr_cwnd_gain
uint32_t rc_initial_hptsi_bw
int32_t bbr_hptsi_segments_max
uint32_t rc_pace_max_segs
uint64_t rc_bbr_cur_del_rate
uint32_t r_app_limited_until
uint32_t rc_lost_at_pktepoch
uint32_t bbr_hdwr_cnt_noset_snt
uint32_t rc_num_maps_alloced
uint32_t rc_num_split_allocs
uint32_t rc_tlp_rxt_last_time
uint32_t rc_target_at_state
uint32_t last_in_probertt
struct time_filter rc_delrate
uint32_t startup_last_srtt
uint32_t rc_bbr_enters_probertt
uint32_t rc_recovery_start
uint32_t rc_bbr_last_startup_epoch
uint32_t bbr_smallest_srtt_this_state
uint32_t rc_last_delay_val
int32_t bbr_hptsi_segments_delay_tar
uint32_t rc_went_idle_time
struct sack_filter bbr_sf
uint32_t highest_hdwr_delay
uint32_t rc_rcv_epoch_start
struct bbr_sendmap * rc_tlp_send
uint32_t rc_bbr_state_time
uint32_t rc_pkt_epoch_rtt
uint32_t rc_bbr_hptsi_gain
uint32_t bbr_lost_at_state
uint32_t bbr_ts_check_our_cts
uint32_t r_measurement_count
struct bbr_sendmap * rc_next
uint32_t rc_bbr_state_atflight
uint32_t cur_rtt_send_time
uint32_t bbr_rttprobe_gain_val
uint32_t rc_ack_hdwr_delay
struct bbr_sendmap * rc_sacklast
uint32_t bbr_peer_tsratio
uint32_t rc_hptsi_agg_delay
uint32_t flightsize_at_drain
uint32_t rc_pace_min_segs
uint32_t bbr_ts_check_tstmp
struct bbr_sendmap * rc_resend
uint32_t bbr_smallest_srtt_state2
struct time_filter_small rc_rttprop
uint16_t rc_reorder_shift
uint16_t bbr_google_discount
int32_t bbr_hptsi_per_second
uint32_t rc_lost_at_startup
uint16_t bbr_hptsi_segments_floor
uint32_t rc_pkt_epoch_loss_rate
uint32_t rc_pkt_epoch_del
uint32_t rc_level_state_extra
uint32_t rc_probertt_srttchktim
uint16_t rc_tlp_seg_send_cnt
uint32_t r_first_sent_time
uint8_t r_rtt_not_allowed
uint32_t r_tim_lastsent[BBR_NUM_OF_RETRANS]
uint32_t r_flight_at_send
struct socket * inp_socket
struct ip6_pktopts * in6p_outputopts
struct route_in6 inp_route6
struct mbuf * inp_options
struct m_snd_tag * inp_snd_tag
struct in_conninfo inp_inc
struct in_addr ip_src ip_dst
uint8_t rc_allow_data_af_clo
int32_t(* r_substate)(struct mbuf *, struct tcphdr *, struct socket *, struct tcpcb *, struct tcpopt *, int32_t, int32_t, uint32_t, int32_t, int32_t, uint8_t)
uint16_t rc_resends_use_tso
uint8_t rc_tlp_in_progress
uint8_t bbr_use_rack_cheat
uint16_t output_error_seen
uint16_t rc_output_starts_timer
uint16_t rc_all_timers_stopped
uint16_t rc_lt_is_sampling
uint16_t rc_ack_was_delayed
uint32_t rc_pacer_started
uint8_t bbr_init_win_cheat
uint8_t rc_use_idle_restart
uint8_t alloc_limit_reported
uint16_t rc_is_pkt_epoch_now
uint16_t rc_has_collapsed
uint8_t rc_ts_cant_be_used
uint8_t bbr_attempt_hdwr_pace
char tfb_tcp_block_name[TCP_FUNCTION_NAME_LEN_MAX]
void(* tfb_tcp_do_segment)(struct mbuf *, struct tcphdr *, struct socket *, struct tcpcb *, int, int, uint8_t)
const struct tcp_rate_set * ptbl
unsigned int * t_tfo_pending
struct sackblk sackblks[MAX_SACK_BLKS]
union tcpcb::@55 t_tfo_cookie
int32_t t_stats_gput_prev
u_int t_pmtud_saved_maxseg
struct statsblob * t_stats
uint8_t t_tfo_client_cookie_len
uint32_t snd_ssthresh_prev
uint8_t client[TCP_FASTOPEN_MAX_COOKIE_LEN]
struct tcp_function_block * t_fb
#define BBR_STATE_STARTUP
#define BBR_HIGHSPEED_NUM_MSS
#define BBR_STARTUP_EPOCHS
#define BBR_RTTS_SHRINK_PG_FINAL
#define BBR_STATE_PROBE_BW
#define BBR_NUM_RTTS_FOR_DEL_LIMIT
#define BBR_RTTS_NEW_TARGET
#define BBR_RWND_COLLAPSED
#define BBR_RTTS_RTTPROBE
#define BBR_RTT_BY_THIS_RETRAN
#define BBR_RECOVERY_LOWRTT
#define BBR_NUM_OF_RETRANS
uint8_t r_rtt_not_allowed
#define BBR_RTTS_RESETS_VALUES
#define BBR_OPTS_INC(name)
#define BBR_RED_BW_USELRBW
#define BBR_TO_FRM_DELACK
#define BBR_RTT_BY_EXACTMATCH
#define BBR_RTTS_SHRINK_PG
#define BBR_STAT_ADD(name, amm)
#define BBR_RTT_BY_SOME_RETRAN
#define BBR_RTT_BY_EARLIER_RET
#define BBR_PROBERTT_NUM_MSS
#define BBR_RTTS_REACHTAR
#define BBR_STATE_PROBE_RTT
#define BBR_RTTS_LEAVE_DRAIN
#define BBR_RTT_BY_TIMESTAMP
#define BBR_LIMIT_TYPE_SPLIT
#define BBR_TO_FRM_PERSIST
#define BBR_SUBSTATE_COUNT
#define BBR_NUM_RTTS_FOR_GOOG_DEL_LIMIT
#define BBR_STAT_INC(name)
#define BBR_STATE_IDLE_EXIT
#define BBR_RTT_BY_TSMATCHING
#define BBR_RTTS_ENTERPROBE
#define BBR_MAX_GAIN_VALUE
void tcp_trace(short act, short ostate, struct tcpcb *tp, void *ipgen, struct tcphdr *th, int req)
void tcp_fastopen_disable_path(struct tcpcb *tp)
void tcp_fastopen_decrement_counter(unsigned int *counter)
void tcp_fastopen_update_cache(struct tcpcb *tp, uint16_t mss, uint8_t cookie_len, uint8_t *cookie)
#define TCP_FASTOPEN_COOKIE_LEN
#define TCPS_HAVERCVDSYN(s)
#define TCPS_HAVERCVDFIN(s)
#define TCPS_SYN_RECEIVED
#define TCPS_HAVEESTABLISHED(s)
void tcp_hpts_remove(struct inpcb *inp)
int32_t tcp_min_hptsi_time
bool tcp_in_hpts(struct inpcb *inp)
uint32_t tcp_hpts_insert_diag(struct inpcb *inp, uint32_t slot, int32_t line, struct hpts_diag *diag)
#define HPTS_USEC_TO_SLOTS(x)
static __inline uint32_t tcp_tv_to_mssectick(const struct timeval *sv)
static __inline uint32_t tcp_tv_to_usectick(const struct timeval *sv)
static __inline uint32_t tcp_get_usecs(struct timeval *tv)
#define tcp_hpts_insert(inp, slot)
struct tcp_log_buffer * tcp_log_event_(struct tcpcb *tp, struct tcphdr *th, struct sockbuf *rxbuf, struct sockbuf *txbuf, uint8_t eventid, int errornum, uint32_t len, union tcp_log_stackspecific *stackinfo, int th_hostorder, const char *output_caller, const char *func, int line, const struct timeval *itv)
#define TCP_LOG_EVENTP(tp, th, rxbuf, txbuf, eventid, errornum, len, stackinfo, th_hostorder, tv)
void tcp_lro_reg_mbufq(void)
void tcp_lro_dereg_mbufq(void)
int tcp_offload_output(struct tcpcb *tp)
int tcp_addoptions(struct tcpopt *to, u_char *optp)
void tcp_sndbuf_autoscale(struct tcpcb *tp, struct socket *so, uint32_t sendwin)
struct mbuf * tcp_m_copym(struct mbuf *m, int32_t off0, int32_t *plen, int32_t seglimit, int32_t segsize, struct sockbuf *sb, bool hw_tls)
static const struct tcp_hwrate_limit_table * tcp_chg_pacing_rate(const struct tcp_hwrate_limit_table *crte, struct tcpcb *tp, struct ifnet *ifp, uint64_t bytes_per_sec, int flags, int *error, uint64_t *lower_rate)
static const struct tcp_hwrate_limit_table * tcp_set_pacing_rate(struct tcpcb *tp, struct ifnet *ifp, uint64_t bytes_per_sec, int flags, int *error, uint64_t *lower_rate)
static void tcp_rel_pacing_rate(const struct tcp_hwrate_limit_table *crte, struct tcpcb *tp)
int tcp_reass(struct tcpcb *tp, struct tcphdr *th, tcp_seq *seq_start, int *tlenp, struct mbuf *m)
void tcp_update_dsack_list(struct tcpcb *tp, tcp_seq rcv_start, tcp_seq rcv_end)
void tcp_clean_sackreport(struct tcpcb *tp)
void tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_start, tcp_seq rcv_end)
void tcp_clean_dsack_blocks(struct tcpcb *tp)
#define tcp_rcvseqinit(tp)
struct tcpcb * tcp_drop(struct tcpcb *tp, int errno)
int deregister_tcp_functions(struct tcp_function_block *blk, bool quiesce, bool force)
int register_tcp_functions_as_names(struct tcp_function_block *blk, int wait, const char *names[], int *num_names)
void tcp_switch_back_to_default(struct tcpcb *tp)
void tcpip_fillheaders(struct inpcb *inp, uint16_t port, void *ip_ptr, void *tcp_ptr)
void tcp_state_change(struct tcpcb *tp, int newstate)
struct tcpcb * tcp_close(struct tcpcb *tp)
void tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m, tcp_seq ack, tcp_seq seq, int flags)
void tcp_log_end_status(struct tcpcb *tp, uint8_t status)
struct tcptemp * tcpip_maketemplate(struct inpcb *inp)
void tcp_record_dsack(struct tcpcb *tp, tcp_seq start, tcp_seq end, int tlp)
int tcp_timer_active(struct tcpcb *tp, uint32_t timer_type)
int tcp_backoff[TCP_MAXRXTSHIFT+1]
int tcp_timer_suspend(struct tcpcb *tp, uint32_t timer_type)
int tcp_rexmit_drop_options
void tcp_timer_activate(struct tcpcb *tp, uint32_t timer_type, u_int delta)
int tcp_fast_finwait2_recycle
#define V_tcp_always_keepalive
#define V_tcp_pmtud_blackhole_detect
#define V_tcp_pmtud_blackhole_mss
#define TCPT_RANGESET(tv, value, tvmin, tvmax)
#define V_tcp_v6pmtud_blackhole_mss
void tcp_twstart(struct tcpcb *tp)
int tcp_default_ctloutput(struct inpcb *inp, struct sockopt *sopt)
#define TCP_EI_STATUS_SERVER_FIN
#define TCP_EI_STATUS_SERVER_RST
#define TCP_EI_STATUS_RST_IN_FRONT
static uint16_t tcp_get_flags(const struct tcphdr *th)
#define TF2_PLPMTU_MAXSEGSNT
#define TCP_EI_STATUS_KEEP_MAX
static void tcp_set_flags(struct tcphdr *th, uint16_t flags)
#define TCP_FUNC_OUTPUT_CANDROP
#define V_tcp_udp_tunneling_port
#define V_tcp_udp_tunneling_overhead
#define TF2_FBYTES_COMPLETE
#define V_tcp_map_entries_limit
#define V_tcp_delack_enabled
#define V_tcp_initcwnd_segments
#define TF2_PLPMTU_BLACKHOLE
#define TCP_EI_STATUS_DATA_A_CLOSE
#define IN_RECOVERY(t_flags)
#define TCP_EI_STATUS_CLIENT_FIN
#define V_tcp_tolerate_missing_ts
#define BYTES_THIS_ACK(tp, th)
#define ENTER_RECOVERY(t_flags)
#define V_tcp_map_split_limit
#define TCP_EI_STATUS_RETRAN
#define KMOD_TCPSTAT_INC(name)
#define IS_FASTOPEN(t_flags)
#define V_path_mtu_discovery
#define KMOD_TCPSTAT_ADD(name, val)
#define EXIT_RECOVERY(t_flags)
#define TCP_EI_STATUS_PERSIST_MAX
static void tcp_account_for_send(struct tcpcb *tp, uint32_t len, uint8_t is_rxt, uint8_t is_tlp, int hw_tls)
#define UDPSTAT_INC(name)