[PATCH 4/5] [DCCP]: Allow changing qpolicy for a socket

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch enables applications to manipulate qpolicy using getsockopt and
setsockopt calls. Qpolicy is inherited on accept().

Signed-off-by: Tomasz Grobelny <tomasz@xxxxxxxxxxxxxxxxxxxxxxx>
---
 include/linux/dccp.h |    1 +
 net/dccp/minisocks.c |    2 +-
 net/dccp/proto.c     |    6 ++++++
 net/dccp/qpolicy.c   |   23 +++++++++++++++++++++++
 net/dccp/qpolicy.h   |    3 +++
 5 files changed, 34 insertions(+), 1 deletions(-)

diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index dfae04f..f3a926a 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -216,6 +216,7 @@ 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_CCID_RX_INFO	128
 #define DCCP_SOCKOPT_CCID_TX_INFO	192
 
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index f9a6211..6e1cbcc 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -142,7 +142,7 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
 			return NULL;
 		}
 		dccp_init_xmit_timers(newsk);
-		dccp_qpolicy_init(newsk);
+		dccp_qpolicy_inherit(newsk, sk);
 
 		DCCP_INC_STATS_BH(DCCP_MIB_PASSIVEOPENS);
 	}
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 7652175..a997b11 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -542,6 +542,9 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
 	case DCCP_SOCKOPT_RECV_CSCOV:
 		err = dccp_setsockopt_cscov(sk, val, true);
 		break;
+	case DCCP_SOCKOPT_QPOLICY_ID:
+		err = dccp_qpolicy_set_id(sk, val);
+		break;
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -645,6 +648,9 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
 	case DCCP_SOCKOPT_RECV_CSCOV:
 		val = dp->dccps_pcrlen;
 		break;
+	case DCCP_SOCKOPT_QPOLICY_ID:
+		val = dccp_qpolicy_get_id(sk);
+		break;
 	case 128 ... 191:
 		return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
 					     len, (u32 __user *)optval, optlen);
diff --git a/net/dccp/qpolicy.c b/net/dccp/qpolicy.c
index 57b5797..35a4b85 100644
--- a/net/dccp/qpolicy.c
+++ b/net/dccp/qpolicy.c
@@ -26,6 +26,29 @@ void dccp_qpolicy_init(struct sock *sk)
 	dp->dccps_qpolicy.qpol_ops = qpolicy_operations[DCCP_QPOLICY_DEFAULT];
 }
 
+int dccp_qpolicy_set_id(struct sock *sk, int id)
+{
+	if (!(sk->sk_state == DCCP_CLOSED) || (sk->sk_state == DCCP_LISTEN))
+		return -EISCONN;
+	if (id >= ARRAY_SIZE(qpolicy_operations))
+		return -EINVAL;
+	dccp_sk(sk)->dccps_qpolicy.qpol_ops = qpolicy_operations[id];
+	return 0;
+}
+
+int dccp_qpolicy_get_id(struct sock *sk)
+{
+	return dccp_sk(sk)->dccps_qpolicy.qpol_ops->policy_id;
+}
+
+void dccp_qpolicy_inherit(struct sock *sk, struct sock *oldsk)
+{
+	struct dccp_sock *dp = dccp_sk(sk);
+
+	int policy_id = dccp_qpolicy_get_id(oldsk);
+	dccp_sk(sk)->dccps_qpolicy.qpol_ops = qpolicy_operations[policy_id];
+
+
 void qpolicy_push(struct sock *sk, struct sk_buff *skb,
 				void *control, __kernel_size_t controllen)
 {
diff --git a/net/dccp/qpolicy.h b/net/dccp/qpolicy.h
index 77aa387..b563a58 100644
--- a/net/dccp/qpolicy.h
+++ b/net/dccp/qpolicy.h
@@ -34,6 +34,9 @@ struct dccp_qpolicy_operations {
 
 /** these operate on data that is common to all policies */
 void dccp_qpolicy_init(struct sock *sk);
+int dccp_qpolicy_set_id(struct sock *sk, int id);
+int dccp_qpolicy_get_id(struct sock *sk);
+void dccp_qpolicy_inherit(struct sock *sk, struct sock *oldsk);
 void dccp_qpolicy_destroy(struct sock *sk);
 
 /** these are wrappers for methods provided by policy currently in use */
-- 
1.5.4.5


--
To unsubscribe from this list: send the line "unsubscribe dccp" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel]     [IETF DCCP]     [Linux Networking]     [Git]     [Security]     [Linux Assembly]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux