diff options
-rw-r--r-- | net/dccp/dccp.h | 1 | ||||
-rw-r--r-- | net/dccp/proto.c | 4 | ||||
-rw-r--r-- | net/dccp/qpolicy.c | 23 |
3 files changed, 22 insertions, 6 deletions
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index d008da91cec2..48ad5d9da7cb 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -251,6 +251,7 @@ extern bool dccp_qpolicy_full(struct sock *sk); | |||
251 | extern void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb); | 251 | extern void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb); |
252 | extern struct sk_buff *dccp_qpolicy_top(struct sock *sk); | 252 | extern struct sk_buff *dccp_qpolicy_top(struct sock *sk); |
253 | extern struct sk_buff *dccp_qpolicy_pop(struct sock *sk); | 253 | extern struct sk_buff *dccp_qpolicy_pop(struct sock *sk); |
254 | extern bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param); | ||
254 | 255 | ||
255 | /* | 256 | /* |
256 | * TX Packet Output and TX Timers | 257 | * TX Packet Output and TX Timers |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index d6a224982bb5..152975d942d9 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -726,6 +726,10 @@ static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb) | |||
726 | if (cmsg->cmsg_level != SOL_DCCP) | 726 | if (cmsg->cmsg_level != SOL_DCCP) |
727 | continue; | 727 | continue; |
728 | 728 | ||
729 | if (cmsg->cmsg_type <= DCCP_SCM_QPOLICY_MAX && | ||
730 | !dccp_qpolicy_param_ok(skb->sk, cmsg->cmsg_type)) | ||
731 | return -EINVAL; | ||
732 | |||
729 | switch (cmsg->cmsg_type) { | 733 | switch (cmsg->cmsg_type) { |
730 | case DCCP_SCM_PRIORITY: | 734 | case DCCP_SCM_PRIORITY: |
731 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u32))) | 735 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u32))) |
diff --git a/net/dccp/qpolicy.c b/net/dccp/qpolicy.c index 4b0fd6b11f6d..63c30bfa4703 100644 --- a/net/dccp/qpolicy.c +++ b/net/dccp/qpolicy.c | |||
@@ -73,17 +73,20 @@ static struct dccp_qpolicy_operations { | |||
73 | void (*push) (struct sock *sk, struct sk_buff *skb); | 73 | void (*push) (struct sock *sk, struct sk_buff *skb); |
74 | bool (*full) (struct sock *sk); | 74 | bool (*full) (struct sock *sk); |
75 | struct sk_buff* (*top) (struct sock *sk); | 75 | struct sk_buff* (*top) (struct sock *sk); |
76 | __be32 params; | ||
76 | 77 | ||
77 | } qpol_table[DCCPQ_POLICY_MAX] = { | 78 | } qpol_table[DCCPQ_POLICY_MAX] = { |
78 | [DCCPQ_POLICY_SIMPLE] = { | 79 | [DCCPQ_POLICY_SIMPLE] = { |
79 | .push = qpolicy_simple_push, | 80 | .push = qpolicy_simple_push, |
80 | .full = qpolicy_simple_full, | 81 | .full = qpolicy_simple_full, |
81 | .top = qpolicy_simple_top, | 82 | .top = qpolicy_simple_top, |
83 | .params = 0, | ||
82 | }, | 84 | }, |
83 | [DCCPQ_POLICY_PRIO] = { | 85 | [DCCPQ_POLICY_PRIO] = { |
84 | .push = qpolicy_simple_push, | 86 | .push = qpolicy_simple_push, |
85 | .full = qpolicy_prio_full, | 87 | .full = qpolicy_prio_full, |
86 | .top = qpolicy_prio_best_skb, | 88 | .top = qpolicy_prio_best_skb, |
89 | .params = DCCP_SCM_PRIORITY, | ||
87 | }, | 90 | }, |
88 | }; | 91 | }; |
89 | 92 | ||
@@ -124,3 +127,11 @@ struct sk_buff *dccp_qpolicy_pop(struct sock *sk) | |||
124 | } | 127 | } |
125 | return skb; | 128 | return skb; |
126 | } | 129 | } |
130 | |||
131 | bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param) | ||
132 | { | ||
133 | /* check if exactly one bit is set */ | ||
134 | if (!param || (param & (param - 1))) | ||
135 | return false; | ||
136 | return (qpol_table[dccp_sk(sk)->dccps_qpolicy].params & param) == param; | ||
137 | } | ||