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 ce2dd6f6f34d..1585fa26488c 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -242,6 +242,7 @@ extern bool dccp_qpolicy_full(struct sock *sk); | |||
242 | extern void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb); | 242 | extern void dccp_qpolicy_drop(struct sock *sk, struct sk_buff *skb); |
243 | extern struct sk_buff *dccp_qpolicy_top(struct sock *sk); | 243 | extern struct sk_buff *dccp_qpolicy_top(struct sock *sk); |
244 | extern struct sk_buff *dccp_qpolicy_pop(struct sock *sk); | 244 | extern struct sk_buff *dccp_qpolicy_pop(struct sock *sk); |
245 | extern bool dccp_qpolicy_param_ok(struct sock *sk, __be32 param); | ||
245 | 246 | ||
246 | /* | 247 | /* |
247 | * TX Packet Output and TX Timers | 248 | * TX Packet Output and TX Timers |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index b56efdd2a421..a3caa11aa836 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -735,6 +735,10 @@ static int dccp_msghdr_parse(struct msghdr *msg, struct sk_buff *skb) | |||
735 | if (cmsg->cmsg_level != SOL_DCCP) | 735 | if (cmsg->cmsg_level != SOL_DCCP) |
736 | continue; | 736 | continue; |
737 | 737 | ||
738 | if (cmsg->cmsg_type <= DCCP_SCM_QPOLICY_MAX && | ||
739 | !dccp_qpolicy_param_ok(skb->sk, cmsg->cmsg_type)) | ||
740 | return -EINVAL; | ||
741 | |||
738 | switch (cmsg->cmsg_type) { | 742 | switch (cmsg->cmsg_type) { |
739 | case DCCP_SCM_PRIORITY: | 743 | case DCCP_SCM_PRIORITY: |
740 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u32))) | 744 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(__u32))) |
diff --git a/net/dccp/qpolicy.c b/net/dccp/qpolicy.c index 414696b0d830..27383f88c75f 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 | skb_unlink(skb, &sk->sk_write_queue); | 127 | skb_unlink(skb, &sk->sk_write_queue); |
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 | } | ||