diff options
author | tuexen <tuexen@FreeBSD.org> | 2011-09-14 08:15:21 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2011-09-14 08:15:21 +0000 |
commit | eab7de0c8f2e020f13c85e1f6c4169d552b72d8e (patch) | |
tree | bfbae5e50e0ce4c3b8e5ca776cf5fb38b53e8bf9 /sys/netinet/sctp_usrreq.c | |
parent | 8494658150198f84d6b4f924e45deb4918496bb3 (diff) | |
download | FreeBSD-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.c | 76 |
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); |