Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  net/dccp/qpolicy.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Policy-based packet dequeueing interface for DCCP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Copyright (c) 2008 Tomasz Grobelny <tomasz@grobelny.oswiecenia.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "dccp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *	Simple Dequeueing Policy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *	If tx_qlen is different from 0, enqueue up to tx_qlen elements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) static void qpolicy_simple_push(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	skb_queue_tail(&sk->sk_write_queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) static bool qpolicy_simple_full(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	return dccp_sk(sk)->dccps_tx_qlen &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	       sk->sk_write_queue.qlen >= dccp_sk(sk)->dccps_tx_qlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static struct sk_buff *qpolicy_simple_top(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	return skb_peek(&sk->sk_write_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  *	Priority-based Dequeueing Policy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  *	If tx_qlen is different from 0 and the queue has reached its upper bound
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  *	of tx_qlen elements, replace older packets lowest-priority-first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static struct sk_buff *qpolicy_prio_best_skb(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	struct sk_buff *skb, *best = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	skb_queue_walk(&sk->sk_write_queue, skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		if (best == NULL || skb->priority > best->priority)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 			best = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	return best;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static struct sk_buff *qpolicy_prio_worst_skb(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	struct sk_buff *skb, *worst = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	skb_queue_walk(&sk->sk_write_queue, skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		if (worst == NULL || skb->priority < worst->priority)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			worst = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	return worst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static bool qpolicy_prio_full(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	if (qpolicy_simple_full(sk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		dccp_qpolicy_drop(sk, qpolicy_prio_worst_skb(sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * struct dccp_qpolicy_operations  -  TX Packet Dequeueing Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * @push: add a new @skb to the write queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * @full: indicates that no more packets will be admitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * @top:  peeks at whatever the queueing policy defines as its `top'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static struct dccp_qpolicy_operations {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	void		(*push)	(struct sock *sk, struct sk_buff *skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	bool		(*full) (struct sock *sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct sk_buff*	(*top)  (struct sock *sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	__be32		params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) } qpol_table[DCCPQ_POLICY_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	[DCCPQ_POLICY_SIMPLE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		.push   = qpolicy_simple_push,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		.full   = qpolicy_simple_full,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		.top    = qpolicy_simple_top,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		.params = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	[DCCPQ_POLICY_PRIO] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		.push   = qpolicy_simple_push,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		.full   = qpolicy_prio_full,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		.top    = qpolicy_prio_best_skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		.params = DCCP_SCM_PRIORITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  *	Externally visible interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) void dccp_qpolicy_push(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	qpol_table[dccp_sk(sk)->dccps_qpolicy].push(sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) bool dccp_qpolicy_full(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return qpol_table[dccp_sk(sk)->dccps_qpolicy].full(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (skb != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		skb_unlink(skb, &sk->sk_write_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct sk_buff *dccp_qpolicy_top(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	return qpol_table[dccp_sk(sk)->dccps_qpolicy].top(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct sk_buff *dccp_qpolicy_pop(struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct sk_buff *skb = dccp_qpolicy_top(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	if (skb != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		/* Clear any skb fields that we used internally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		skb->priority = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		skb_unlink(skb, &sk->sk_write_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	/* check if exactly one bit is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	if (!param || (param & (param - 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	return (qpol_table[dccp_sk(sk)->dccps_qpolicy].params & param) == param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }