Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2bdea157 authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 05bd97fc 0999f021
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -801,4 +801,11 @@ struct sctp_strreset_resptsn {
	__be32 receivers_next_tsn;
};

enum {
	SCTP_DSCP_SET_MASK = 0x1,
	SCTP_DSCP_VAL_MASK = 0xfc,
	SCTP_FLOWLABEL_SET_MASK = 0x100000,
	SCTP_FLOWLABEL_VAL_MASK = 0xfffff
};

#endif /* __LINUX_SCTP_H__ */
+8 −1
Original line number Diff line number Diff line
@@ -148,7 +148,8 @@ void ip_send_check(struct iphdr *ip);
int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);

int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
		    __u8 tos);
void ip_init(void);
int ip_append_data(struct sock *sk, struct flowi4 *fl4,
		   int getfrag(void *from, char *to, int offset, int len,
@@ -174,6 +175,12 @@ struct sk_buff *ip_make_skb(struct sock *sk, struct flowi4 *fl4,
			    struct ipcm_cookie *ipc, struct rtable **rtp,
			    struct inet_cork *cork, unsigned int flags);

static inline int ip_queue_xmit(struct sock *sk, struct sk_buff *skb,
				struct flowi *fl)
{
	return __ip_queue_xmit(sk, skb, fl, inet_sk(sk)->tos);
}

static inline struct sk_buff *ip_finish_skb(struct sock *sk, struct flowi4 *fl4)
{
	return __ip_make_skb(sk, fl4, &sk->sk_write_queue, &inet_sk(sk)->cork.base);
+9 −0
Original line number Diff line number Diff line
@@ -193,6 +193,9 @@ struct sctp_sock {
	/* This is the max_retrans value for new associations. */
	__u16 pathmaxrxt;

	__u32 flowlabel;
	__u8  dscp;

	/* The initial Path MTU to use for new associations. */
	__u32 pathmtu;

@@ -895,6 +898,9 @@ struct sctp_transport {
	 */
	__u16 pathmaxrxt;

	__u32 flowlabel;
	__u8  dscp;

	/* This is the partially failed retrans value for the transport
	 * and will be initialized from the assocs value.  This can be changed
	 * using the SCTP_PEER_ADDR_THLDS socket option
@@ -1772,6 +1778,9 @@ struct sctp_association {
	 */
	__u16 pathmaxrxt;

	__u32 flowlabel;
	__u8  dscp;

	/* Flag that path mtu update is pending */
	__u8   pmtu_pending;

+4 −0
Original line number Diff line number Diff line
@@ -763,6 +763,8 @@ enum sctp_spp_flags {
	SPP_SACKDELAY_DISABLE = 1<<6,	/*Disable SACK*/
	SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE,
	SPP_HB_TIME_IS_ZERO = 1<<7,	/* Set HB delay to 0 */
	SPP_IPV6_FLOWLABEL = 1<<8,
	SPP_DSCP = 1<<9,
};

struct sctp_paddrparams {
@@ -773,6 +775,8 @@ struct sctp_paddrparams {
	__u32			spp_pathmtu;
	__u32			spp_sackdelay;
	__u32			spp_flags;
	__u32			spp_ipv6_flowlabel;
	__u8			spp_dscp;
} __attribute__((packed, aligned(4)));

/*
+5 −4
Original line number Diff line number Diff line
@@ -423,7 +423,8 @@ static void ip_copy_addrs(struct iphdr *iph, const struct flowi4 *fl4)
}

/* Note: skb->sk can be different from sk, in case of tunnels */
int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl)
int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
		    __u8 tos)
{
	struct inet_sock *inet = inet_sk(sk);
	struct net *net = sock_net(sk);
@@ -462,7 +463,7 @@ int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl)
					   inet->inet_dport,
					   inet->inet_sport,
					   sk->sk_protocol,
					   RT_CONN_FLAGS(sk),
					   RT_CONN_FLAGS_TOS(sk, tos),
					   sk->sk_bound_dev_if);
		if (IS_ERR(rt))
			goto no_route;
@@ -478,7 +479,7 @@ int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl)
	skb_push(skb, sizeof(struct iphdr) + (inet_opt ? inet_opt->opt.optlen : 0));
	skb_reset_network_header(skb);
	iph = ip_hdr(skb);
	*((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
	*((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (tos & 0xff));
	if (ip_dont_fragment(sk, &rt->dst) && !skb->ignore_df)
		iph->frag_off = htons(IP_DF);
	else
@@ -511,7 +512,7 @@ int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl)
	kfree_skb(skb);
	return -EHOSTUNREACH;
}
EXPORT_SYMBOL(ip_queue_xmit);
EXPORT_SYMBOL(__ip_queue_xmit);

static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
{
Loading