summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_usrreq.c
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2011-09-14 08:15:21 +0000
committertuexen <tuexen@FreeBSD.org>2011-09-14 08:15:21 +0000
commiteab7de0c8f2e020f13c85e1f6c4169d552b72d8e (patch)
treebfbae5e50e0ce4c3b8e5ca776cf5fb38b53e8bf9 /sys/netinet/sctp_usrreq.c
parent8494658150198f84d6b4f924e45deb4918496bb3 (diff)
downloadFreeBSD-src-eab7de0c8f2e020f13c85e1f6c4169d552b72d8e.zip
FreeBSD-src-eab7de0c8f2e020f13c85e1f6c4169d552b72d8e.tar.gz
Fix the handling of the flowlabel and DSCP value in the SCTP_PEER_ADDR_PARAMS
socket option. Honor the net.inet6.ip6.auto_flowlabel sysctl setting. Approved by: re (bz) MFC after: 1 month.
Diffstat (limited to 'sys/netinet/sctp_usrreq.c')
-rw-r--r--sys/netinet/sctp_usrreq.c76
1 files changed, 48 insertions, 28 deletions
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 0e52909..d52df50 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -2428,15 +2428,14 @@ flags_out:
} else {
paddrp->spp_flags |= SPP_PMTUD_DISABLE;
}
-#ifdef INET
- if (net->ro._l_addr.sin.sin_family == AF_INET) {
- paddrp->spp_dscp = net->dscp;
+ if (net->dscp & 0x01) {
+ paddrp->spp_dscp = net->dscp >> 2;
paddrp->spp_flags |= SPP_DSCP;
}
-#endif
#ifdef INET6
- if (net->ro._l_addr.sin6.sin6_family == AF_INET6) {
- paddrp->spp_ipv6_flowlabel = net->flowlabel;
+ if ((net->ro._l_addr.sa.sa_family == AF_INET6) &&
+ (net->flowlabel & 0x80000000)) {
+ paddrp->spp_ipv6_flowlabel = net->flowlabel & 0x000fffff;
paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
}
#endif
@@ -2449,13 +2448,15 @@ flags_out:
paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc);
-#ifdef INET
- paddrp->spp_dscp = stcb->asoc.default_dscp & 0x000000fc;
- paddrp->spp_flags |= SPP_DSCP;
-#endif
+ if (stcb->asoc.default_dscp & 0x01) {
+ paddrp->spp_dscp = stcb->asoc.default_dscp >> 2;
+ paddrp->spp_flags |= SPP_DSCP;
+ }
#ifdef INET6
- paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel;
- paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
+ if (stcb->asoc.default_flowlabel & 0x80000000) {
+ paddrp->spp_ipv6_flowlabel = stcb->asoc.default_flowlabel & 0x000fffff;
+ paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
+ }
#endif
/* default settings should be these */
if (sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
@@ -2485,13 +2486,14 @@ flags_out:
paddrp->spp_hbinterval = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
paddrp->spp_assoc_id = SCTP_FUTURE_ASSOC;
/* get inp's default */
-#ifdef INET
- paddrp->spp_dscp = inp->ip_inp.inp.inp_ip_tos;
- paddrp->spp_flags |= SPP_DSCP;
-#endif
+ if (inp->sctp_ep.default_dscp & 0x01) {
+ paddrp->spp_dscp = inp->sctp_ep.default_dscp >> 2;
+ paddrp->spp_flags |= SPP_DSCP;
+ }
#ifdef INET6
- if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
- paddrp->spp_ipv6_flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo;
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
+ (inp->sctp_ep.default_flowlabel & 0x80000000)) {
+ paddrp->spp_ipv6_flowlabel = inp->sctp_ep.default_flowlabel & 0x000fffff;
paddrp->spp_flags |= SPP_IPV6_FLOWLABEL;
}
#endif
@@ -4683,17 +4685,15 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
net->failure_threshold = paddrp->spp_pathmaxrxt;
}
-#ifdef INET
if (paddrp->spp_flags & SPP_DSCP) {
- if (net->ro._l_addr.sin.sin_family == AF_INET) {
- net->dscp = paddrp->spp_dscp & 0xfc;
- }
+ net->dscp = paddrp->spp_dscp << 2;
+ net->dscp |= 0x01;
}
-#endif
#ifdef INET6
if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
- if (net->ro._l_addr.sin6.sin6_family == AF_INET6) {
+ if (net->ro._l_addr.sa.sa_family == AF_INET6) {
net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
+ net->flowlabel |= 0x80000000;
}
}
#endif
@@ -4784,16 +4784,24 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
if (paddrp->spp_flags & SPP_DSCP) {
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
- net->dscp = paddrp->spp_dscp & 0x000000fc;
+ net->dscp = paddrp->spp_dscp << 2;
+ net->dscp |= 0x01;
}
- stcb->asoc.default_dscp = paddrp->spp_dscp & 0x000000fc;
+ stcb->asoc.default_dscp = paddrp->spp_dscp << 2;
+ stcb->asoc.default_dscp |= 0x01;
}
+#ifdef INET6
if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
- net->flowlabel = paddrp->spp_ipv6_flowlabel;
+ if (net->ro._l_addr.sa.sa_family == AF_INET6) {
+ net->flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
+ net->flowlabel |= 0x80000000;
+ }
}
- stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel;
+ stcb->asoc.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
+ stcb->asoc.default_flowlabel |= 0x80000000;
}
+#endif
}
SCTP_TCB_UNLOCK(stcb);
} else {
@@ -4827,6 +4835,18 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
} else if (paddrp->spp_flags & SPP_HB_DISABLE) {
sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
}
+ if (paddrp->spp_flags & SPP_DSCP) {
+ inp->sctp_ep.default_dscp = paddrp->spp_dscp << 2;
+ inp->sctp_ep.default_dscp |= 0x01;
+ }
+#ifdef INET6
+ if (paddrp->spp_flags & SPP_IPV6_FLOWLABEL) {
+ if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) {
+ inp->sctp_ep.default_flowlabel = paddrp->spp_ipv6_flowlabel & 0x000fffff;
+ inp->sctp_ep.default_flowlabel |= 0x80000000;
+ }
+ }
+#endif
SCTP_INP_WUNLOCK(inp);
} else {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
OpenPOWER on IntegriCloud