[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   |   20 ++++++++++++++++++++
 net/dccp/qpolicy.h   |    3 +++
 5 files changed, 31 insertions(+), 1 deletions(-)
-- 
Regards,
Tomasz Grobelny
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 3484a4a..3b40133 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -208,6 +208,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 f3916ac..24e56a2 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -544,6 +544,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;
@@ -647,6 +650,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 df8861a..7315bf0 100644
--- a/net/dccp/qpolicy.c
+++ b/net/dccp/qpolicy.c
@@ -27,6 +27,26 @@ 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)
+{
+	struct dccp_sock *dp = dccp_sk(sk);
+	if(id >= ARRAY_SIZE(qpolicy_operations))
+		return -EINVAL;
+	dp->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)
+{
+	dccp_qpolicy_init(sk);
+	dccp_qpolicy_set_id(sk, dccp_qpolicy_get_id(oldsk));
+}
+
 void dccp_qpolicy_destroy(struct sock *sk)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
diff --git a/net/dccp/qpolicy.h b/net/dccp/qpolicy.h
index dd4b94d..ccfbf1b 100644
--- a/net/dccp/qpolicy.h
+++ b/net/dccp/qpolicy.h
@@ -36,6 +36,9 @@ struct dccp_qpolicy
 
 /** 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 */

[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