0001
0002 #ifndef _CCID_H
0003 #define _CCID_H
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <net/sock.h>
0014 #include <linux/compiler.h>
0015 #include <linux/dccp.h>
0016 #include <linux/list.h>
0017 #include <linux/module.h>
0018
0019
0020 #define CCID_MAX 255
0021 #define CCID_SLAB_NAME_LENGTH 32
0022
0023 struct tcp_info;
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 struct ccid_operations {
0046 unsigned char ccid_id;
0047 __u32 ccid_ccmps;
0048 const char *ccid_name;
0049 struct kmem_cache *ccid_hc_rx_slab,
0050 *ccid_hc_tx_slab;
0051 char ccid_hc_rx_slab_name[CCID_SLAB_NAME_LENGTH];
0052 char ccid_hc_tx_slab_name[CCID_SLAB_NAME_LENGTH];
0053 __u32 ccid_hc_rx_obj_size,
0054 ccid_hc_tx_obj_size;
0055
0056 int (*ccid_hc_rx_init)(struct ccid *ccid, struct sock *sk);
0057 int (*ccid_hc_tx_init)(struct ccid *ccid, struct sock *sk);
0058 void (*ccid_hc_rx_exit)(struct sock *sk);
0059 void (*ccid_hc_tx_exit)(struct sock *sk);
0060 void (*ccid_hc_rx_packet_recv)(struct sock *sk,
0061 struct sk_buff *skb);
0062 int (*ccid_hc_rx_parse_options)(struct sock *sk, u8 pkt,
0063 u8 opt, u8 *val, u8 len);
0064 int (*ccid_hc_rx_insert_options)(struct sock *sk,
0065 struct sk_buff *skb);
0066 void (*ccid_hc_tx_packet_recv)(struct sock *sk,
0067 struct sk_buff *skb);
0068 int (*ccid_hc_tx_parse_options)(struct sock *sk, u8 pkt,
0069 u8 opt, u8 *val, u8 len);
0070 int (*ccid_hc_tx_send_packet)(struct sock *sk,
0071 struct sk_buff *skb);
0072 void (*ccid_hc_tx_packet_sent)(struct sock *sk,
0073 unsigned int len);
0074 void (*ccid_hc_rx_get_info)(struct sock *sk,
0075 struct tcp_info *info);
0076 void (*ccid_hc_tx_get_info)(struct sock *sk,
0077 struct tcp_info *info);
0078 int (*ccid_hc_rx_getsockopt)(struct sock *sk,
0079 const int optname, int len,
0080 u32 __user *optval,
0081 int __user *optlen);
0082 int (*ccid_hc_tx_getsockopt)(struct sock *sk,
0083 const int optname, int len,
0084 u32 __user *optval,
0085 int __user *optlen);
0086 };
0087
0088 extern struct ccid_operations ccid2_ops;
0089 #ifdef CONFIG_IP_DCCP_CCID3
0090 extern struct ccid_operations ccid3_ops;
0091 #endif
0092
0093 int ccid_initialize_builtins(void);
0094 void ccid_cleanup_builtins(void);
0095
0096 struct ccid {
0097 struct ccid_operations *ccid_ops;
0098 char ccid_priv[];
0099 };
0100
0101 static inline void *ccid_priv(const struct ccid *ccid)
0102 {
0103 return (void *)ccid->ccid_priv;
0104 }
0105
0106 bool ccid_support_check(u8 const *ccid_array, u8 array_len);
0107 int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len);
0108 int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
0109 char __user *, int __user *);
0110
0111 struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx);
0112
0113 static inline int ccid_get_current_rx_ccid(struct dccp_sock *dp)
0114 {
0115 struct ccid *ccid = dp->dccps_hc_rx_ccid;
0116
0117 if (ccid == NULL || ccid->ccid_ops == NULL)
0118 return -1;
0119 return ccid->ccid_ops->ccid_id;
0120 }
0121
0122 static inline int ccid_get_current_tx_ccid(struct dccp_sock *dp)
0123 {
0124 struct ccid *ccid = dp->dccps_hc_tx_ccid;
0125
0126 if (ccid == NULL || ccid->ccid_ops == NULL)
0127 return -1;
0128 return ccid->ccid_ops->ccid_id;
0129 }
0130
0131 void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk);
0132 void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk);
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 enum ccid_dequeueing_decision {
0145 CCID_PACKET_SEND_AT_ONCE = 0x00000,
0146 CCID_PACKET_DELAY_MAX = 0x0FFFF,
0147 CCID_PACKET_DELAY = 0x10000,
0148 CCID_PACKET_WILL_DEQUEUE_LATER = 0x20000,
0149 CCID_PACKET_ERR = 0xF0000,
0150 };
0151
0152 static inline int ccid_packet_dequeue_eval(const int return_code)
0153 {
0154 if (return_code < 0)
0155 return CCID_PACKET_ERR;
0156 if (return_code == 0)
0157 return CCID_PACKET_SEND_AT_ONCE;
0158 if (return_code <= CCID_PACKET_DELAY_MAX)
0159 return CCID_PACKET_DELAY;
0160 return return_code;
0161 }
0162
0163 static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk,
0164 struct sk_buff *skb)
0165 {
0166 if (ccid->ccid_ops->ccid_hc_tx_send_packet != NULL)
0167 return ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb);
0168 return CCID_PACKET_SEND_AT_ONCE;
0169 }
0170
0171 static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk,
0172 unsigned int len)
0173 {
0174 if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL)
0175 ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, len);
0176 }
0177
0178 static inline void ccid_hc_rx_packet_recv(struct ccid *ccid, struct sock *sk,
0179 struct sk_buff *skb)
0180 {
0181 if (ccid->ccid_ops->ccid_hc_rx_packet_recv != NULL)
0182 ccid->ccid_ops->ccid_hc_rx_packet_recv(sk, skb);
0183 }
0184
0185 static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk,
0186 struct sk_buff *skb)
0187 {
0188 if (ccid->ccid_ops->ccid_hc_tx_packet_recv != NULL)
0189 ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb);
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199 static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk,
0200 u8 pkt, u8 opt, u8 *val, u8 len)
0201 {
0202 if (!ccid || !ccid->ccid_ops->ccid_hc_tx_parse_options)
0203 return 0;
0204 return ccid->ccid_ops->ccid_hc_tx_parse_options(sk, pkt, opt, val, len);
0205 }
0206
0207
0208
0209
0210
0211 static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
0212 u8 pkt, u8 opt, u8 *val, u8 len)
0213 {
0214 if (!ccid || !ccid->ccid_ops->ccid_hc_rx_parse_options)
0215 return 0;
0216 return ccid->ccid_ops->ccid_hc_rx_parse_options(sk, pkt, opt, val, len);
0217 }
0218
0219 static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
0220 struct sk_buff *skb)
0221 {
0222 if (ccid->ccid_ops->ccid_hc_rx_insert_options != NULL)
0223 return ccid->ccid_ops->ccid_hc_rx_insert_options(sk, skb);
0224 return 0;
0225 }
0226
0227 static inline void ccid_hc_rx_get_info(struct ccid *ccid, struct sock *sk,
0228 struct tcp_info *info)
0229 {
0230 if (ccid->ccid_ops->ccid_hc_rx_get_info != NULL)
0231 ccid->ccid_ops->ccid_hc_rx_get_info(sk, info);
0232 }
0233
0234 static inline void ccid_hc_tx_get_info(struct ccid *ccid, struct sock *sk,
0235 struct tcp_info *info)
0236 {
0237 if (ccid->ccid_ops->ccid_hc_tx_get_info != NULL)
0238 ccid->ccid_ops->ccid_hc_tx_get_info(sk, info);
0239 }
0240
0241 static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk,
0242 const int optname, int len,
0243 u32 __user *optval, int __user *optlen)
0244 {
0245 int rc = -ENOPROTOOPT;
0246 if (ccid != NULL && ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL)
0247 rc = ccid->ccid_ops->ccid_hc_rx_getsockopt(sk, optname, len,
0248 optval, optlen);
0249 return rc;
0250 }
0251
0252 static inline int ccid_hc_tx_getsockopt(struct ccid *ccid, struct sock *sk,
0253 const int optname, int len,
0254 u32 __user *optval, int __user *optlen)
0255 {
0256 int rc = -ENOPROTOOPT;
0257 if (ccid != NULL && ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL)
0258 rc = ccid->ccid_ops->ccid_hc_tx_getsockopt(sk, optname, len,
0259 optval, optlen);
0260 return rc;
0261 }
0262 #endif