Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'sctp-fully-support-for-dscp-and-flowlabel-per-transport'

Xin Long says:

====================
sctp: fully support for dscp and flowlabel per transport

Now dscp and flowlabel are set from sock when sending the packets,
but being multi-homing, sctp also supports for dscp and flowlabel
per transport, which is described in section 8.1.12 in RFC6458.

v1->v2:
- define ip_queue_xmit as inline in net/ip.h, instead of exporting
it in Patch 1/5 according to David's suggestion.
- fix the param len check in sctp_s/getsockopt_peer_addr_params()
in Patch 3/5 to guarantee that an old app built with old kernel
headers could work on the newer kernel per Marcelo's point.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+254 -17
+7
include/linux/sctp.h
··· 801 801 __be32 receivers_next_tsn; 802 802 }; 803 803 804 + enum { 805 + SCTP_DSCP_SET_MASK = 0x1, 806 + SCTP_DSCP_VAL_MASK = 0xfc, 807 + SCTP_FLOWLABEL_SET_MASK = 0x100000, 808 + SCTP_FLOWLABEL_VAL_MASK = 0xfffff 809 + }; 810 + 804 811 #endif /* __LINUX_SCTP_H__ */
+8 -1
include/net/ip.h
··· 148 148 int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); 149 149 int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); 150 150 151 - int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); 151 + int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 152 + __u8 tos); 152 153 void ip_init(void); 153 154 int ip_append_data(struct sock *sk, struct flowi4 *fl4, 154 155 int getfrag(void *from, char *to, int offset, int len, ··· 174 173 void *from, int length, int transhdrlen, 175 174 struct ipcm_cookie *ipc, struct rtable **rtp, 176 175 struct inet_cork *cork, unsigned int flags); 176 + 177 + static inline int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, 178 + struct flowi *fl) 179 + { 180 + return __ip_queue_xmit(sk, skb, fl, inet_sk(sk)->tos); 181 + } 177 182 178 183 static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4) 179 184 {
+9
include/net/sctp/structs.h
··· 193 193 /* This is the max_retrans value for new associations. */ 194 194 __u16 pathmaxrxt; 195 195 196 + __u32 flowlabel; 197 + __u8 dscp; 198 + 196 199 /* The initial Path MTU to use for new associations. */ 197 200 __u32 pathmtu; 198 201 ··· 897 894 * using the SCTP_SET_PEER_ADDR_PARAMS socket option. 898 895 */ 899 896 __u16 pathmaxrxt; 897 + 898 + __u32 flowlabel; 899 + __u8 dscp; 900 900 901 901 /* This is the partially failed retrans value for the transport 902 902 * and will be initialized from the assocs value. This can be changed ··· 1777 1771 * association. 1778 1772 */ 1779 1773 __u16 pathmaxrxt; 1774 + 1775 + __u32 flowlabel; 1776 + __u8 dscp; 1780 1777 1781 1778 /* Flag that path mtu update is pending */ 1782 1779 __u8 pmtu_pending;
+4
include/uapi/linux/sctp.h
··· 763 763 SPP_SACKDELAY_DISABLE = 1<<6, /*Disable SACK*/ 764 764 SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE, 765 765 SPP_HB_TIME_IS_ZERO = 1<<7, /* Set HB delay to 0 */ 766 + SPP_IPV6_FLOWLABEL = 1<<8, 767 + SPP_DSCP = 1<<9, 766 768 }; 767 769 768 770 struct sctp_paddrparams { ··· 775 773 __u32 spp_pathmtu; 776 774 __u32 spp_sackdelay; 777 775 __u32 spp_flags; 776 + __u32 spp_ipv6_flowlabel; 777 + __u8 spp_dscp; 778 778 } __attribute__((packed, aligned(4))); 779 779 780 780 /*
+5 -4
net/ipv4/ip_output.c
··· 423 423 } 424 424 425 425 /* Note: skb->sk can be different from sk, in case of tunnels */ 426 - int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl) 426 + int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 427 + __u8 tos) 427 428 { 428 429 struct inet_sock *inet = inet_sk(sk); 429 430 struct net *net = sock_net(sk); ··· 463 462 inet->inet_dport, 464 463 inet->inet_sport, 465 464 sk->sk_protocol, 466 - RT_CONN_FLAGS(sk), 465 + RT_CONN_FLAGS_TOS(sk, tos), 467 466 sk->sk_bound_dev_if); 468 467 if (IS_ERR(rt)) 469 468 goto no_route; ··· 479 478 skb_push(skb, sizeof(struct iphdr) + (inet_opt ? inet_opt->opt.optlen : 0)); 480 479 skb_reset_network_header(skb); 481 480 iph = ip_hdr(skb); 482 - *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff)); 481 + *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (tos & 0xff)); 483 482 if (ip_dont_fragment(sk, &rt->dst) && !skb->ignore_df) 484 483 iph->frag_off = htons(IP_DF); 485 484 else ··· 512 511 kfree_skb(skb); 513 512 return -EHOSTUNREACH; 514 513 } 515 - EXPORT_SYMBOL(ip_queue_xmit); 514 + EXPORT_SYMBOL(__ip_queue_xmit); 516 515 517 516 static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) 518 517 {
+15
net/sctp/associola.c
··· 115 115 /* Initialize path max retrans value. */ 116 116 asoc->pathmaxrxt = sp->pathmaxrxt; 117 117 118 + asoc->flowlabel = sp->flowlabel; 119 + asoc->dscp = sp->dscp; 120 + 118 121 /* Initialize default path MTU. */ 119 122 asoc->pathmtu = sp->pathmtu; 120 123 ··· 649 646 */ 650 647 peer->sackdelay = asoc->sackdelay; 651 648 peer->sackfreq = asoc->sackfreq; 649 + 650 + if (addr->sa.sa_family == AF_INET6) { 651 + __be32 info = addr->v6.sin6_flowinfo; 652 + 653 + if (info) { 654 + peer->flowlabel = ntohl(info & IPV6_FLOWLABEL_MASK); 655 + peer->flowlabel |= SCTP_FLOWLABEL_SET_MASK; 656 + } else { 657 + peer->flowlabel = asoc->flowlabel; 658 + } 659 + } 660 + peer->dscp = asoc->dscp; 652 661 653 662 /* Enable/disable heartbeat, SACK delay, and path MTU discovery 654 663 * based on association setting.
+18 -2
net/sctp/ipv6.c
··· 209 209 struct sock *sk = skb->sk; 210 210 struct ipv6_pinfo *np = inet6_sk(sk); 211 211 struct flowi6 *fl6 = &transport->fl.u.ip6; 212 + __u8 tclass = np->tclass; 212 213 int res; 213 214 214 215 pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb, 215 216 skb->len, &fl6->saddr, &fl6->daddr); 216 217 217 - IP6_ECN_flow_xmit(sk, fl6->flowlabel); 218 + if (transport->dscp & SCTP_DSCP_SET_MASK) 219 + tclass = transport->dscp & SCTP_DSCP_VAL_MASK; 220 + 221 + if (INET_ECN_is_capable(tclass)) 222 + IP6_ECN_flow_xmit(sk, fl6->flowlabel); 218 223 219 224 if (!(transport->param_flags & SPP_PMTUD_ENABLE)) 220 225 skb->ignore_df = 1; ··· 228 223 229 224 rcu_read_lock(); 230 225 res = ip6_xmit(sk, skb, fl6, sk->sk_mark, rcu_dereference(np->opt), 231 - np->tclass); 226 + tclass); 232 227 rcu_read_unlock(); 233 228 return res; 234 229 } ··· 259 254 fl6->flowi6_oif = daddr->v6.sin6_scope_id; 260 255 else if (asoc) 261 256 fl6->flowi6_oif = asoc->base.sk->sk_bound_dev_if; 257 + if (t->flowlabel & SCTP_FLOWLABEL_SET_MASK) 258 + fl6->flowlabel = htonl(t->flowlabel & SCTP_FLOWLABEL_VAL_MASK); 259 + 260 + if (np->sndflow && (fl6->flowlabel & IPV6_FLOWLABEL_MASK)) { 261 + struct ip6_flowlabel *flowlabel; 262 + 263 + flowlabel = fl6_sock_lookup(sk, fl6->flowlabel); 264 + if (!flowlabel) 265 + goto out; 266 + fl6_sock_release(flowlabel); 267 + } 262 268 263 269 pr_debug("%s: dst=%pI6 ", __func__, &fl6->daddr); 264 270
+12 -4
net/sctp/protocol.c
··· 426 426 struct dst_entry *dst = NULL; 427 427 union sctp_addr *daddr = &t->ipaddr; 428 428 union sctp_addr dst_saddr; 429 + __u8 tos = inet_sk(sk)->tos; 429 430 431 + if (t->dscp & SCTP_DSCP_SET_MASK) 432 + tos = t->dscp & SCTP_DSCP_VAL_MASK; 430 433 memset(fl4, 0x0, sizeof(struct flowi4)); 431 434 fl4->daddr = daddr->v4.sin_addr.s_addr; 432 435 fl4->fl4_dport = daddr->v4.sin_port; 433 436 fl4->flowi4_proto = IPPROTO_SCTP; 434 437 if (asoc) { 435 - fl4->flowi4_tos = RT_CONN_FLAGS(asoc->base.sk); 438 + fl4->flowi4_tos = RT_CONN_FLAGS_TOS(asoc->base.sk, tos); 436 439 fl4->flowi4_oif = asoc->base.sk->sk_bound_dev_if; 437 440 fl4->fl4_sport = htons(asoc->base.bind_addr.port); 438 441 } ··· 498 495 fl4->fl4_sport = laddr->a.v4.sin_port; 499 496 flowi4_update_output(fl4, 500 497 asoc->base.sk->sk_bound_dev_if, 501 - RT_CONN_FLAGS(asoc->base.sk), 498 + RT_CONN_FLAGS_TOS(asoc->base.sk, tos), 502 499 daddr->v4.sin_addr.s_addr, 503 500 laddr->a.v4.sin_addr.s_addr); 504 501 ··· 974 971 struct sctp_transport *transport) 975 972 { 976 973 struct inet_sock *inet = inet_sk(skb->sk); 974 + __u8 dscp = inet->tos; 977 975 978 976 pr_debug("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n", __func__, skb, 979 - skb->len, &transport->fl.u.ip4.saddr, &transport->fl.u.ip4.daddr); 977 + skb->len, &transport->fl.u.ip4.saddr, 978 + &transport->fl.u.ip4.daddr); 979 + 980 + if (transport->dscp & SCTP_DSCP_SET_MASK) 981 + dscp = transport->dscp & SCTP_DSCP_VAL_MASK; 980 982 981 983 inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ? 982 984 IP_PMTUDISC_DO : IP_PMTUDISC_DONT; 983 985 984 986 SCTP_INC_STATS(sock_net(&inet->sk), SCTP_MIB_OUTSCTPPACKS); 985 987 986 - return ip_queue_xmit(&inet->sk, skb, &transport->fl); 988 + return __ip_queue_xmit(&inet->sk, skb, &transport->fl, dscp); 987 989 } 988 990 989 991 static struct sctp_af sctp_af_inet;
+176 -6
net/sctp/socket.c
··· 1697 1697 struct sctp_association *asoc; 1698 1698 enum sctp_scope scope; 1699 1699 struct cmsghdr *cmsg; 1700 + __be32 flowinfo = 0; 1700 1701 struct sctp_af *af; 1701 1702 int err; 1702 1703 ··· 1782 1781 if (!cmsgs->addrs_msg) 1783 1782 return 0; 1784 1783 1784 + if (daddr->sa.sa_family == AF_INET6) 1785 + flowinfo = daddr->v6.sin6_flowinfo; 1786 + 1785 1787 /* sendv addr list parse */ 1786 1788 for_each_cmsghdr(cmsg, cmsgs->addrs_msg) { 1787 1789 struct sctp_transport *transport; ··· 1817 1813 } 1818 1814 1819 1815 dlen = sizeof(struct in6_addr); 1816 + daddr->v6.sin6_flowinfo = flowinfo; 1820 1817 daddr->v6.sin6_family = AF_INET6; 1821 1818 daddr->v6.sin6_port = htons(asoc->peer.port); 1822 1819 memcpy(&daddr->v6.sin6_addr, CMSG_DATA(cmsg), dlen); ··· 2398 2393 * uint32_t spp_pathmtu; 2399 2394 * uint32_t spp_sackdelay; 2400 2395 * uint32_t spp_flags; 2396 + * uint32_t spp_ipv6_flowlabel; 2397 + * uint8_t spp_dscp; 2401 2398 * }; 2402 2399 * 2403 2400 * spp_assoc_id - (one-to-many style socket) This is filled in the ··· 2479 2472 * also that this field is mutually exclusive to 2480 2473 * SPP_SACKDELAY_ENABLE, setting both will have undefined 2481 2474 * results. 2475 + * 2476 + * SPP_IPV6_FLOWLABEL: Setting this flag enables the 2477 + * setting of the IPV6 flow label value. The value is 2478 + * contained in the spp_ipv6_flowlabel field. 2479 + * Upon retrieval, this flag will be set to indicate that 2480 + * the spp_ipv6_flowlabel field has a valid value returned. 2481 + * If a specific destination address is set (in the 2482 + * spp_address field), then the value returned is that of 2483 + * the address. If just an association is specified (and 2484 + * no address), then the association's default flow label 2485 + * is returned. If neither an association nor a destination 2486 + * is specified, then the socket's default flow label is 2487 + * returned. For non-IPv6 sockets, this flag will be left 2488 + * cleared. 2489 + * 2490 + * SPP_DSCP: Setting this flag enables the setting of the 2491 + * Differentiated Services Code Point (DSCP) value 2492 + * associated with either the association or a specific 2493 + * address. The value is obtained in the spp_dscp field. 2494 + * Upon retrieval, this flag will be set to indicate that 2495 + * the spp_dscp field has a valid value returned. If a 2496 + * specific destination address is set when called (in the 2497 + * spp_address field), then that specific destination 2498 + * address's DSCP value is returned. If just an association 2499 + * is specified, then the association's default DSCP is 2500 + * returned. If neither an association nor a destination is 2501 + * specified, then the socket's default DSCP is returned. 2502 + * 2503 + * spp_ipv6_flowlabel 2504 + * - This field is used in conjunction with the 2505 + * SPP_IPV6_FLOWLABEL flag and contains the IPv6 flow label. 2506 + * The 20 least significant bits are used for the flow 2507 + * label. This setting has precedence over any IPv6-layer 2508 + * setting. 2509 + * 2510 + * spp_dscp - This field is used in conjunction with the SPP_DSCP flag 2511 + * and contains the DSCP. The 6 most significant bits are 2512 + * used for the DSCP. This setting has precedence over any 2513 + * IPv4- or IPv6- layer setting. 2482 2514 */ 2483 2515 static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, 2484 2516 struct sctp_transport *trans, ··· 2657 2611 } 2658 2612 } 2659 2613 2614 + if (params->spp_flags & SPP_IPV6_FLOWLABEL) { 2615 + if (trans && trans->ipaddr.sa.sa_family == AF_INET6) { 2616 + trans->flowlabel = params->spp_ipv6_flowlabel & 2617 + SCTP_FLOWLABEL_VAL_MASK; 2618 + trans->flowlabel |= SCTP_FLOWLABEL_SET_MASK; 2619 + } else if (asoc) { 2620 + list_for_each_entry(trans, 2621 + &asoc->peer.transport_addr_list, 2622 + transports) { 2623 + if (trans->ipaddr.sa.sa_family != AF_INET6) 2624 + continue; 2625 + trans->flowlabel = params->spp_ipv6_flowlabel & 2626 + SCTP_FLOWLABEL_VAL_MASK; 2627 + trans->flowlabel |= SCTP_FLOWLABEL_SET_MASK; 2628 + } 2629 + asoc->flowlabel = params->spp_ipv6_flowlabel & 2630 + SCTP_FLOWLABEL_VAL_MASK; 2631 + asoc->flowlabel |= SCTP_FLOWLABEL_SET_MASK; 2632 + } else if (sctp_opt2sk(sp)->sk_family == AF_INET6) { 2633 + sp->flowlabel = params->spp_ipv6_flowlabel & 2634 + SCTP_FLOWLABEL_VAL_MASK; 2635 + sp->flowlabel |= SCTP_FLOWLABEL_SET_MASK; 2636 + } 2637 + } 2638 + 2639 + if (params->spp_flags & SPP_DSCP) { 2640 + if (trans) { 2641 + trans->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK; 2642 + trans->dscp |= SCTP_DSCP_SET_MASK; 2643 + } else if (asoc) { 2644 + list_for_each_entry(trans, 2645 + &asoc->peer.transport_addr_list, 2646 + transports) { 2647 + trans->dscp = params->spp_dscp & 2648 + SCTP_DSCP_VAL_MASK; 2649 + trans->dscp |= SCTP_DSCP_SET_MASK; 2650 + } 2651 + asoc->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK; 2652 + asoc->dscp |= SCTP_DSCP_SET_MASK; 2653 + } else { 2654 + sp->dscp = params->spp_dscp & SCTP_DSCP_VAL_MASK; 2655 + sp->dscp |= SCTP_DSCP_SET_MASK; 2656 + } 2657 + } 2658 + 2660 2659 return 0; 2661 2660 } 2662 2661 ··· 2716 2625 int error; 2717 2626 int hb_change, pmtud_change, sackdelay_change; 2718 2627 2719 - if (optlen != sizeof(struct sctp_paddrparams)) 2628 + if (optlen == sizeof(params)) { 2629 + if (copy_from_user(&params, optval, optlen)) 2630 + return -EFAULT; 2631 + } else if (optlen == ALIGN(offsetof(struct sctp_paddrparams, 2632 + spp_ipv6_flowlabel), 4)) { 2633 + if (copy_from_user(&params, optval, optlen)) 2634 + return -EFAULT; 2635 + if (params.spp_flags & (SPP_DSCP | SPP_IPV6_FLOWLABEL)) 2636 + return -EINVAL; 2637 + } else { 2720 2638 return -EINVAL; 2721 - 2722 - if (copy_from_user(&params, optval, optlen)) 2723 - return -EFAULT; 2639 + } 2724 2640 2725 2641 /* Validate flags and value parameters. */ 2726 2642 hb_change = params.spp_flags & SPP_HB; ··· 5551 5453 * also that this field is mutually exclusive to 5552 5454 * SPP_SACKDELAY_ENABLE, setting both will have undefined 5553 5455 * results. 5456 + * 5457 + * SPP_IPV6_FLOWLABEL: Setting this flag enables the 5458 + * setting of the IPV6 flow label value. The value is 5459 + * contained in the spp_ipv6_flowlabel field. 5460 + * Upon retrieval, this flag will be set to indicate that 5461 + * the spp_ipv6_flowlabel field has a valid value returned. 5462 + * If a specific destination address is set (in the 5463 + * spp_address field), then the value returned is that of 5464 + * the address. If just an association is specified (and 5465 + * no address), then the association's default flow label 5466 + * is returned. If neither an association nor a destination 5467 + * is specified, then the socket's default flow label is 5468 + * returned. For non-IPv6 sockets, this flag will be left 5469 + * cleared. 5470 + * 5471 + * SPP_DSCP: Setting this flag enables the setting of the 5472 + * Differentiated Services Code Point (DSCP) value 5473 + * associated with either the association or a specific 5474 + * address. The value is obtained in the spp_dscp field. 5475 + * Upon retrieval, this flag will be set to indicate that 5476 + * the spp_dscp field has a valid value returned. If a 5477 + * specific destination address is set when called (in the 5478 + * spp_address field), then that specific destination 5479 + * address's DSCP value is returned. If just an association 5480 + * is specified, then the association's default DSCP is 5481 + * returned. If neither an association nor a destination is 5482 + * specified, then the socket's default DSCP is returned. 5483 + * 5484 + * spp_ipv6_flowlabel 5485 + * - This field is used in conjunction with the 5486 + * SPP_IPV6_FLOWLABEL flag and contains the IPv6 flow label. 5487 + * The 20 least significant bits are used for the flow 5488 + * label. This setting has precedence over any IPv6-layer 5489 + * setting. 5490 + * 5491 + * spp_dscp - This field is used in conjunction with the SPP_DSCP flag 5492 + * and contains the DSCP. The 6 most significant bits are 5493 + * used for the DSCP. This setting has precedence over any 5494 + * IPv4- or IPv6- layer setting. 5554 5495 */ 5555 5496 static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, 5556 5497 char __user *optval, int __user *optlen) ··· 5599 5462 struct sctp_association *asoc = NULL; 5600 5463 struct sctp_sock *sp = sctp_sk(sk); 5601 5464 5602 - if (len < sizeof(struct sctp_paddrparams)) 5465 + if (len >= sizeof(params)) 5466 + len = sizeof(params); 5467 + else if (len >= ALIGN(offsetof(struct sctp_paddrparams, 5468 + spp_ipv6_flowlabel), 4)) 5469 + len = ALIGN(offsetof(struct sctp_paddrparams, 5470 + spp_ipv6_flowlabel), 4); 5471 + else 5603 5472 return -EINVAL; 5604 - len = sizeof(struct sctp_paddrparams); 5473 + 5605 5474 if (copy_from_user(&params, optval, len)) 5606 5475 return -EFAULT; 5607 5476 ··· 5642 5499 5643 5500 /*draft-11 doesn't say what to return in spp_flags*/ 5644 5501 params.spp_flags = trans->param_flags; 5502 + if (trans->flowlabel & SCTP_FLOWLABEL_SET_MASK) { 5503 + params.spp_ipv6_flowlabel = trans->flowlabel & 5504 + SCTP_FLOWLABEL_VAL_MASK; 5505 + params.spp_flags |= SPP_IPV6_FLOWLABEL; 5506 + } 5507 + if (trans->dscp & SCTP_DSCP_SET_MASK) { 5508 + params.spp_dscp = trans->dscp & SCTP_DSCP_VAL_MASK; 5509 + params.spp_flags |= SPP_DSCP; 5510 + } 5645 5511 } else if (asoc) { 5646 5512 /* Fetch association values. */ 5647 5513 params.spp_hbinterval = jiffies_to_msecs(asoc->hbinterval); ··· 5660 5508 5661 5509 /*draft-11 doesn't say what to return in spp_flags*/ 5662 5510 params.spp_flags = asoc->param_flags; 5511 + if (asoc->flowlabel & SCTP_FLOWLABEL_SET_MASK) { 5512 + params.spp_ipv6_flowlabel = asoc->flowlabel & 5513 + SCTP_FLOWLABEL_VAL_MASK; 5514 + params.spp_flags |= SPP_IPV6_FLOWLABEL; 5515 + } 5516 + if (asoc->dscp & SCTP_DSCP_SET_MASK) { 5517 + params.spp_dscp = asoc->dscp & SCTP_DSCP_VAL_MASK; 5518 + params.spp_flags |= SPP_DSCP; 5519 + } 5663 5520 } else { 5664 5521 /* Fetch socket values. */ 5665 5522 params.spp_hbinterval = sp->hbinterval; ··· 5678 5517 5679 5518 /*draft-11 doesn't say what to return in spp_flags*/ 5680 5519 params.spp_flags = sp->param_flags; 5520 + if (sp->flowlabel & SCTP_FLOWLABEL_SET_MASK) { 5521 + params.spp_ipv6_flowlabel = sp->flowlabel & 5522 + SCTP_FLOWLABEL_VAL_MASK; 5523 + params.spp_flags |= SPP_IPV6_FLOWLABEL; 5524 + } 5525 + if (sp->dscp & SCTP_DSCP_SET_MASK) { 5526 + params.spp_dscp = sp->dscp & SCTP_DSCP_VAL_MASK; 5527 + params.spp_flags |= SPP_DSCP; 5528 + } 5681 5529 } 5682 5530 5683 5531 if (copy_to_user(optval, &params, len))