diff options
Diffstat (limited to 'net/dccp/ccid.c')
-rw-r--r-- | net/dccp/ccid.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c index 8fe931a3d7a1..647cb0614f84 100644 --- a/net/dccp/ccid.c +++ b/net/dccp/ccid.c | |||
@@ -13,6 +13,13 @@ | |||
13 | 13 | ||
14 | #include "ccid.h" | 14 | #include "ccid.h" |
15 | 15 | ||
16 | static u8 builtin_ccids[] = { | ||
17 | DCCPC_CCID2, /* CCID2 is supported by default */ | ||
18 | #if defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE) | ||
19 | DCCPC_CCID3, | ||
20 | #endif | ||
21 | }; | ||
22 | |||
16 | static struct ccid_operations *ccids[CCID_MAX]; | 23 | static struct ccid_operations *ccids[CCID_MAX]; |
17 | #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) | 24 | #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) |
18 | static atomic_t ccids_lockct = ATOMIC_INIT(0); | 25 | static atomic_t ccids_lockct = ATOMIC_INIT(0); |
@@ -86,6 +93,47 @@ static void ccid_kmem_cache_destroy(struct kmem_cache *slab) | |||
86 | } | 93 | } |
87 | } | 94 | } |
88 | 95 | ||
96 | /* check that up to @array_len members in @ccid_array are supported */ | ||
97 | bool ccid_support_check(u8 const *ccid_array, u8 array_len) | ||
98 | { | ||
99 | u8 i, j, found; | ||
100 | |||
101 | for (i = 0, found = 0; i < array_len; i++, found = 0) { | ||
102 | for (j = 0; !found && j < ARRAY_SIZE(builtin_ccids); j++) | ||
103 | found = (ccid_array[i] == builtin_ccids[j]); | ||
104 | if (!found) | ||
105 | return false; | ||
106 | } | ||
107 | return true; | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * ccid_get_builtin_ccids - Provide copy of `builtin' CCID array | ||
112 | * @ccid_array: pointer to copy into | ||
113 | * @array_len: value to return length into | ||
114 | * This function allocates memory - caller must see that it is freed after use. | ||
115 | */ | ||
116 | int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len) | ||
117 | { | ||
118 | *ccid_array = kmemdup(builtin_ccids, sizeof(builtin_ccids), gfp_any()); | ||
119 | if (*ccid_array == NULL) | ||
120 | return -ENOBUFS; | ||
121 | *array_len = ARRAY_SIZE(builtin_ccids); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | int ccid_getsockopt_builtin_ccids(struct sock *sk, int len, | ||
126 | char __user *optval, int __user *optlen) | ||
127 | { | ||
128 | if (len < sizeof(builtin_ccids)) | ||
129 | return -EINVAL; | ||
130 | |||
131 | if (put_user(sizeof(builtin_ccids), optlen) || | ||
132 | copy_to_user(optval, builtin_ccids, sizeof(builtin_ccids))) | ||
133 | return -EFAULT; | ||
134 | return 0; | ||
135 | } | ||
136 | |||
89 | int ccid_register(struct ccid_operations *ccid_ops) | 137 | int ccid_register(struct ccid_operations *ccid_ops) |
90 | { | 138 | { |
91 | int err = -ENOBUFS; | 139 | int err = -ENOBUFS; |