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

Commit d6da3511 authored by Tomasz Grobelny's avatar Tomasz Grobelny Committed by Gerrit Renker
Browse files

dccp: Policy-based packet dequeueing infrastructure



This patch adds a generic infrastructure for policy-based dequeueing of 
TX packets and provides two policies:
 * a simple FIFO policy (which is the default) and
 * a priority based policy (set via socket options).
Both policies honour the tx_qlen sysctl for the maximum size of the write
queue (can be overridden via socket options). 

The priority policy uses skb->priority internally to assign an u32 priority
identifier, using the same ranking as SO_PRIORITY. The skb->priority field
is set to 0 when the packet leaves DCCP. The priority is supplied as ancillary
data using cmsg(3), the patch also provides the requisite parsing routines.

Signed-off-by: default avatarTomasz Grobelny <tomasz@grobelny.oswiecenia.net>
Signed-off-by: default avatarGerrit Renker <gerrit@erg.abdn.ac.uk>
parent ddab0556
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -45,6 +45,25 @@ http://linux-net.osdl.org/index.php/DCCP_Testing#Experimental_DCCP_source_tree

Socket options
==============
DCCP_SOCKOPT_QPOLICY_ID sets the dequeuing policy for outgoing packets. It takes
a policy ID as argument and can only be set before the connection (i.e. changes
during an established connection are not supported). Currently, two policies are
defined: the "simple" policy (DCCPQ_POLICY_SIMPLE), which does nothing special,
and a priority-based variant (DCCPQ_POLICY_PRIO). The latter allows to pass an
u32 priority value as ancillary data to sendmsg(), where higher numbers indicate
a higher packet priority (similar to SO_PRIORITY). This ancillary data needs to
be formatted using a cmsg(3) message header filled in as follows:
	cmsg->cmsg_level = SOL_DCCP;
	cmsg->cmsg_type	 = DCCP_SCM_PRIORITY;
	cmsg->cmsg_len	 = CMSG_LEN(sizeof(uint32_t));	/* or CMSG_LEN(4) */

DCCP_SOCKOPT_QPOLICY_TXQLEN sets the maximum length of the output queue. A zero
value is always interpreted as unbounded queue length. If different from zero,
the interpretation of this parameter depends on the current dequeuing policy
(see above): the "simple" policy will enforce a fixed queue size by returning
EAGAIN, whereas the "prio" policy enforces a fixed queue length by dropping the
lowest-priority packet first. The default value for this parameter is
initialised from /proc/sys/net/dccp/default/tx_qlen.

DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of
service codes (RFC 4340, sec. 8.1.2); if this socket option is not set,
+21 −0
Original line number Diff line number Diff line
@@ -197,6 +197,21 @@ enum dccp_feature_numbers {
	DCCPF_MAX_CCID_SPECIFIC = 255,
};

/* DCCP socket control message types for cmsg */
enum dccp_cmsg_type {
	DCCP_SCM_PRIORITY = 1,
	DCCP_SCM_QPOLICY_MAX = 0xFFFF,
	/* ^-- Up to here reserved exclusively for qpolicy parameters */
	DCCP_SCM_MAX
};

/* DCCP priorities for outgoing/queued packets */
enum dccp_packet_dequeueing_policy {
	DCCPQ_POLICY_SIMPLE,
	DCCPQ_POLICY_PRIO,
	DCCPQ_POLICY_MAX
};

/* DCCP socket options */
#define DCCP_SOCKOPT_PACKET_SIZE	1 /* XXX deprecated, without effect */
#define DCCP_SOCKOPT_SERVICE		2
@@ -210,6 +225,8 @@ enum dccp_feature_numbers {
#define DCCP_SOCKOPT_CCID		13
#define DCCP_SOCKOPT_TX_CCID		14
#define DCCP_SOCKOPT_RX_CCID		15
#define DCCP_SOCKOPT_QPOLICY_ID		16
#define DCCP_SOCKOPT_QPOLICY_TXQLEN	17
#define DCCP_SOCKOPT_CCID_RX_INFO	128
#define DCCP_SOCKOPT_CCID_TX_INFO	192

@@ -458,6 +475,8 @@ struct dccp_ackvec;
 * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection)
 * @dccps_hc_tx_ccid - CCID used for the sender (or sending half-connection)
 * @dccps_options_received - parsed set of retrieved options
 * @dccps_qpolicy - TX dequeueing policy, one of %dccp_packet_dequeueing_policy
 * @dccps_tx_qlen - maximum length of the TX queue
 * @dccps_role - role of this sock, one of %dccp_role
 * @dccps_hc_rx_insert_options - receiver wants to add options when acking
 * @dccps_hc_tx_insert_options - sender wants to add options when sending
@@ -500,6 +519,8 @@ struct dccp_sock {
	struct ccid			*dccps_hc_rx_ccid;
	struct ccid			*dccps_hc_tx_ccid;
	struct dccp_options_received	dccps_options_received;
	__u8				dccps_qpolicy;
	__u32				dccps_tx_qlen;
	enum dccp_role			dccps_role:2;
	__u8				dccps_hc_rx_insert_options:1;
	__u8				dccps_hc_tx_insert_options:1;
+1 −1
Original line number Diff line number Diff line
obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv4.o

dccp-y := ccid.o feat.o input.o minisocks.o options.o \
	  output.o proto.o timer.o ackvec.o
	  qpolicy.o output.o proto.o timer.o ackvec.o

dccp_ipv4-y := ipv4.o

+12 −0
Original line number Diff line number Diff line
@@ -234,6 +234,18 @@ extern void dccp_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
extern void dccp_send_sync(struct sock *sk, const u64 seq,
			   const enum dccp_pkt_type pkt_type);

/*
 * TX Packet Dequeueing Interface
 */
extern void		dccp_qpolicy_push(struct sock *sk, struct sk_buff *skb);
extern bool		dccp_qpolicy_full(struct sock *sk);
extern void		dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb);
extern struct sk_buff	*dccp_qpolicy_top(struct sock *sk);
extern struct sk_buff	*dccp_qpolicy_pop(struct sock *sk);

/*
 * TX Packet Output and TX Timers
 */
extern void dccp_write_xmit(struct sock *sk);
extern void dccp_write_space(struct sock *sk);
extern void dccp_flush_write_queue(struct sock *sk, long *time_budget);
+3 −4
Original line number Diff line number Diff line
@@ -241,7 +241,7 @@ static void dccp_xmit_packet(struct sock *sk)
{
	int err, len;
	struct dccp_sock *dp = dccp_sk(sk);
	struct sk_buff *skb = skb_dequeue(&sk->sk_write_queue);
	struct sk_buff *skb = dccp_qpolicy_pop(sk);

	if (unlikely(skb == NULL))
		return;
@@ -344,7 +344,7 @@ void dccp_write_xmit(struct sock *sk)
	struct dccp_sock *dp = dccp_sk(sk);
	struct sk_buff *skb;

	while ((skb = skb_peek(&sk->sk_write_queue))) {
	while ((skb = dccp_qpolicy_top(sk))) {
		int rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);

		switch (ccid_packet_dequeue_eval(rc)) {
@@ -358,8 +358,7 @@ void dccp_write_xmit(struct sock *sk)
			dccp_xmit_packet(sk);
			break;
		case CCID_PACKET_ERR:
			skb_dequeue(&sk->sk_write_queue);
			kfree_skb(skb);
			dccp_qpolicy_drop(sk, skb);
			dccp_pr_debug("packet discarded due to err=%d\n", rc);
		}
	}
Loading