Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148543067
D32600.id97358.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D32600.id97358.diff
View Options
Index: sys/netinet/tcp_stacks/bbr.c
===================================================================
--- sys/netinet/tcp_stacks/bbr.c
+++ sys/netinet/tcp_stacks/bbr.c
@@ -14238,6 +14238,7 @@
.tfb_tcp_handoff_ok = bbr_handoff_ok,
.tfb_tcp_mtu_chg = bbr_mtu_chg,
.tfb_pru_options = bbr_pru_options,
+ .tfb_tcp_ll_socketopt = tcp_ll_socketopt,
};
/*
Index: sys/netinet/tcp_stacks/rack.c
===================================================================
--- sys/netinet/tcp_stacks/rack.c
+++ sys/netinet/tcp_stacks/rack.c
@@ -12508,6 +12508,7 @@
ip6, rack->r_ctl.fsb.th);
} else
#endif /* INET6 */
+#ifdef INET
{
rack->r_ctl.fsb.tcp_ip_hdr_len = sizeof(struct tcpiphdr);
ip = (struct ip *)rack->r_ctl.fsb.tcp_ip_hdr;
@@ -12527,9 +12528,80 @@
tp->t_port,
ip, rack->r_ctl.fsb.th);
}
+#endif
rack->r_fsb_inited = 1;
}
+static void
+rack_ll_socketopt(struct tcpcb *tp, int sopt_level, int sopt_name)
+{
+#ifdef INET6
+ struct ip6_hdr *ip6 = NULL;
+#endif
+#ifdef INET
+ struct ip *ip = NULL;
+#endif
+ struct tcp_rack *rack;
+ /*
+ * A socket option changed the outgoing TOS/TCLASS update
+ * the fast send block.
+ */
+ rack = (struct tcp_rack *)tp->t_fb_ptr;
+#ifdef INET6
+ /*
+ * In case of the IPV6_USE_MIN_MTU socket option,
+ * the INC_IPV6MINMTU flag to announce a corresponding
+ * MSS during the initial handshake.
+ * If the TCP connection is not in the front states,
+ * just reduce the MSS being used.
+ * This avoids the sending of TCP segments which will
+ * be fragmented at the IPv6 layer.
+ */
+ if ((sopt_level == IPPROTO_IPV6) &&
+ (sopt_name == IPV6_USE_MIN_MTU)) {
+ tp->t_inpcb->inp_inc.inc_flags |= INC_IPV6MINMTU;
+ if ((tp->t_state >= TCPS_SYN_SENT) &&
+ (tp->t_inpcb->inp_inc.inc_flags & INC_ISIPV6)) {
+ struct ip6_pktopts *opt;
+
+ opt = tp->t_inpcb->in6p_outputopts;
+ if ((opt != NULL) &&
+ (opt->ip6po_minmtu ==
+ IP6PO_MINMTU_ALL)) {
+ if (tp->t_maxseg > TCP6_MSS) {
+ tp->t_maxseg = TCP6_MSS;
+ }
+ }
+ }
+ } else if ((sopt_level == IPPROTO_IPV6) &&
+ (sopt_name == IPV6_TCLASS)) {
+ /*
+ * The DSCP codepoint has changed, update the fsb.
+ */
+ ip6 = (struct ip6_hdr *)rack->r_ctl.fsb.tcp_ip_hdr;
+ ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
+ (rack->rc_inp->inp_flow & IPV6_FLOWINFO_MASK);
+ }
+#endif
+#ifdef INET
+ else if ((sopt_level == IPPROTO_IP) &&
+ (sopt_name == IP_TOS)) {
+ /*
+ * The DSCP codepoint has changed, update the fsb.
+ */
+ ip = (struct ip *)rack->r_ctl.fsb.tcp_ip_hdr;
+ ip->ip_tos = rack->rc_inp->inp_ip_tos;
+ } else if ((sopt_level == IPPROTO_IP) &&
+ (sopt_name == IP_TTL)) {
+ /*
+ * The TTL has changed, update the fsb.
+ */
+ ip = (struct ip *)rack->r_ctl.fsb.tcp_ip_hdr;
+ ip->ip_ttl = rack->rc_inp->inp_ip_ttl;
+ }
+#endif
+}
+
static int
rack_init_fsb(struct tcpcb *tp, struct tcp_rack *rack)
{
@@ -20232,6 +20304,7 @@
.tfb_tcp_mtu_chg = rack_mtu_change,
.tfb_pru_options = rack_pru_options,
.tfb_hwtls_change = rack_hw_tls_change,
+ .tfb_tcp_ll_socketopt = rack_ll_socketopt,
};
/*
Index: sys/netinet/tcp_subr.c
===================================================================
--- sys/netinet/tcp_subr.c
+++ sys/netinet/tcp_subr.c
@@ -384,6 +384,7 @@
.tfb_tcp_handoff_ok = tcp_default_handoff_ok,
.tfb_tcp_fb_init = tcp_default_fb_init,
.tfb_tcp_fb_fini = tcp_default_fb_fini,
+ .tfb_tcp_ll_socketopt = tcp_ll_socketopt,
};
static int tcp_fb_cnt = 0;
@@ -4129,3 +4130,4 @@
}
}
}
+
Index: sys/netinet/tcp_usrreq.c
===================================================================
--- sys/netinet/tcp_usrreq.c
+++ sys/netinet/tcp_usrreq.c
@@ -1712,6 +1712,37 @@
#endif
}
+void
+tcp_ll_socketopt(struct tcpcb *tp, int sopt_level, int sopt_name)
+{
+ /*
+ * In case of the IPV6_USE_MIN_MTU socket option,
+ * the INC_IPV6MINMTU flag to announce a corresponding
+ * MSS during the initial handshake.
+ * If the TCP connection is not in the front states,
+ * just reduce the MSS being used.
+ * This avoids the sending of TCP segments which will
+ * be fragmented at the IPv6 layer.
+ */
+ if ((sopt_level == IPPROTO_IPV6) &&
+ (sopt_name == IPV6_USE_MIN_MTU)) {
+ tp->t_inpcb->inp_inc.inc_flags |= INC_IPV6MINMTU;
+ if ((tp->t_state >= TCPS_SYN_SENT) &&
+ (tp->t_inpcb->inp_inc.inc_flags & INC_ISIPV6)) {
+ struct ip6_pktopts *opt;
+
+ opt = tp->t_inpcb->in6p_outputopts;
+ if ((opt != NULL) &&
+ (opt->ip6po_minmtu ==
+ IP6PO_MINMTU_ALL)) {
+ if (tp->t_maxseg > TCP6_MSS) {
+ tp->t_maxseg = TCP6_MSS;
+ }
+ }
+ }
+ }
+}
+
/*
* tcp_ctloutput() must drop the inpcb lock before performing copyin on
* socket option arguments. When it re-acquires the lock after the copy, it
@@ -1746,41 +1777,24 @@
if (inp->inp_vflag & INP_IPV6PROTO) {
error = ip6_ctloutput(so, sopt);
/*
- * In case of the IPV6_USE_MIN_MTU socket option,
- * the INC_IPV6MINMTU flag to announce a corresponding
- * MSS during the initial handshake.
- * If the TCP connection is not in the front states,
- * just reduce the MSS being used.
- * This avoids the sending of TCP segments which will
- * be fragmented at the IPv6 layer.
+ * If the TCLASS changes we need to
+ * notify tcp stacks that care.
*/
- if ((error == 0) &&
- (sopt->sopt_dir == SOPT_SET) &&
- (sopt->sopt_level == IPPROTO_IPV6) &&
- (sopt->sopt_name == IPV6_USE_MIN_MTU)) {
- INP_WLOCK(inp);
- if ((inp->inp_flags &
- (INP_TIMEWAIT | INP_DROPPED))) {
- INP_WUNLOCK(inp);
- return (ECONNRESET);
- }
- inp->inp_inc.inc_flags |= INC_IPV6MINMTU;
- tp = intotcpcb(inp);
- if ((tp->t_state >= TCPS_SYN_SENT) &&
- (inp->inp_inc.inc_flags & INC_ISIPV6)) {
- struct ip6_pktopts *opt;
-
- opt = inp->in6p_outputopts;
- if ((opt != NULL) &&
- (opt->ip6po_minmtu ==
- IP6PO_MINMTU_ALL)) {
- if (tp->t_maxseg > TCP6_MSS) {
- tp->t_maxseg = TCP6_MSS;
- }
- }
- }
+ INP_WLOCK(inp);
+ if ((inp->inp_flags &
+ (INP_TIMEWAIT | INP_DROPPED))) {
INP_WUNLOCK(inp);
+ return (ECONNRESET);
}
+ tp = intotcpcb(inp);
+ if (tp->t_fb->tfb_tcp_ll_socketopt != NULL) {
+ /*
+ * This stack wants to know about DSCP codepoint
+ * changes.
+ */
+ (tp->t_fb->tfb_tcp_ll_socketopt)(tp, sopt->sopt_level, sopt->sopt_name);
+ }
+ INP_WUNLOCK(inp);
}
#endif /* INET6 */
#if defined(INET6) && defined(INET)
@@ -1788,7 +1802,26 @@
#endif
#ifdef INET
{
+ /*
+ * If the TOS changes we need to
+ * notify tcp stacks that care.
+ */
error = ip_ctloutput(so, sopt);
+ INP_WLOCK(inp);
+ if ((inp->inp_flags &
+ (INP_TIMEWAIT | INP_DROPPED))) {
+ INP_WUNLOCK(inp);
+ return (ECONNRESET);
+ }
+ tp = intotcpcb(inp);
+ if (tp->t_fb->tfb_tcp_ll_socketopt != NULL) {
+ /*
+ * This stack wants to know about lower level
+ * option changes.
+ */
+ (tp->t_fb->tfb_tcp_ll_socketopt)(tp, sopt->sopt_level, sopt->sopt_name);
+ }
+ INP_WUNLOCK(inp);
}
#endif
return (error);
Index: sys/netinet/tcp_var.h
===================================================================
--- sys/netinet/tcp_var.h
+++ sys/netinet/tcp_var.h
@@ -373,6 +373,7 @@
void (*tfb_tcp_mtu_chg)(struct tcpcb *);
int (*tfb_pru_options)(struct tcpcb *, int);
void (*tfb_hwtls_change)(struct tcpcb *, int);
+ void (*tfb_tcp_ll_socketopt)(struct tcpcb *, int, int);
volatile uint32_t tfb_refcnt;
uint32_t tfb_flags;
uint8_t tfb_id;
@@ -990,6 +991,7 @@
struct tcpcb *, int, int);
void tcp_pulloutofband(struct socket *,
struct tcphdr *, struct mbuf *, int);
+void tcp_ll_socketopt(struct tcpcb *, int , int);
void tcp_xmit_timer(struct tcpcb *, int);
void tcp_newreno_partial_ack(struct tcpcb *, struct tcphdr *);
void cc_ack_received(struct tcpcb *tp, struct tcphdr *th,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 19, 2:57 PM (10 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29967304
Default Alt Text
D32600.id97358.diff (7 KB)
Attached To
Mode
D32600: tcp: DSCP Codepoint not being propagated in the rack fast path.
Attached
Detach File
Event Timeline
Log In to Comment