Page MenuHomeFreeBSD

D32600.id97358.diff
No OneTemporary

D32600.id97358.diff

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

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)

Event Timeline