diff options
author | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:30:19 -0400 |
---|---|---|
committer | Gerrit Renker <gerrit@erg.abdn.ac.uk> | 2008-09-04 01:45:32 -0400 |
commit | 76f738a7950b559a23ab3c692c99a02f35a54f7f (patch) | |
tree | 51d8b63cc209821f73ae3af89a151d8185967c88 | |
parent | 0a4822679d94e2b0117aeead06a19fad59533905 (diff) |
dccp: Debugging functions for feature negotiation
Since all feature-negotiation processing now takes place in feat.c, functions
for producing verbose debugging output are concentrated there.
New functions to print out values, entry records, and options are provided,
and also a macro is defined to not always have the function name in the
output line.
Thanks a lot to Wei Yongjun and Giuseppe Galeota for help with errors in an
earlier revision of this patch.
Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
-rw-r--r-- | net/dccp/dccp.h | 2 | ||||
-rw-r--r-- | net/dccp/feat.c | 153 | ||||
-rw-r--r-- | net/dccp/feat.h | 13 | ||||
-rw-r--r-- | net/dccp/options.c | 4 |
4 files changed, 109 insertions, 63 deletions
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 4f681f1a16cc..94ae6d41d724 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -42,9 +42,11 @@ | |||
42 | extern int dccp_debug; | 42 | extern int dccp_debug; |
43 | #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a) | 43 | #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a) |
44 | #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a) | 44 | #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a) |
45 | #define dccp_debug(fmt, a...) dccp_pr_debug_cat(KERN_DEBUG fmt, ##a) | ||
45 | #else | 46 | #else |
46 | #define dccp_pr_debug(format, a...) | 47 | #define dccp_pr_debug(format, a...) |
47 | #define dccp_pr_debug_cat(format, a...) | 48 | #define dccp_pr_debug_cat(format, a...) |
49 | #define dccp_debug(format, a...) | ||
48 | #endif | 50 | #endif |
49 | 51 | ||
50 | extern struct inet_hashinfo dccp_hashinfo; | 52 | extern struct inet_hashinfo dccp_hashinfo; |
diff --git a/net/dccp/feat.c b/net/dccp/feat.c index 4c95cbdb0e01..3abacad0b224 100644 --- a/net/dccp/feat.c +++ b/net/dccp/feat.c | |||
@@ -204,6 +204,100 @@ static int dccp_feat_default_value(u8 feat_num) | |||
204 | return idx < 0 ? : dccp_feat_table[idx].default_value; | 204 | return idx < 0 ? : dccp_feat_table[idx].default_value; |
205 | } | 205 | } |
206 | 206 | ||
207 | /* | ||
208 | * Debugging and verbose-printing section | ||
209 | */ | ||
210 | static const char *dccp_feat_fname(const u8 feat) | ||
211 | { | ||
212 | static const char *feature_names[] = { | ||
213 | [DCCPF_RESERVED] = "Reserved", | ||
214 | [DCCPF_CCID] = "CCID", | ||
215 | [DCCPF_SHORT_SEQNOS] = "Allow Short Seqnos", | ||
216 | [DCCPF_SEQUENCE_WINDOW] = "Sequence Window", | ||
217 | [DCCPF_ECN_INCAPABLE] = "ECN Incapable", | ||
218 | [DCCPF_ACK_RATIO] = "Ack Ratio", | ||
219 | [DCCPF_SEND_ACK_VECTOR] = "Send ACK Vector", | ||
220 | [DCCPF_SEND_NDP_COUNT] = "Send NDP Count", | ||
221 | [DCCPF_MIN_CSUM_COVER] = "Min. Csum Coverage", | ||
222 | [DCCPF_DATA_CHECKSUM] = "Send Data Checksum", | ||
223 | }; | ||
224 | if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC) | ||
225 | return feature_names[DCCPF_RESERVED]; | ||
226 | |||
227 | if (feat == DCCPF_SEND_LEV_RATE) | ||
228 | return "Send Loss Event Rate"; | ||
229 | if (feat >= DCCPF_MIN_CCID_SPECIFIC) | ||
230 | return "CCID-specific"; | ||
231 | |||
232 | return feature_names[feat]; | ||
233 | } | ||
234 | |||
235 | static const char *dccp_feat_sname[] = { "DEFAULT", "INITIALISING", "CHANGING", | ||
236 | "UNSTABLE", "STABLE" }; | ||
237 | |||
238 | #ifdef CONFIG_IP_DCCP_DEBUG | ||
239 | static const char *dccp_feat_oname(const u8 opt) | ||
240 | { | ||
241 | switch (opt) { | ||
242 | case DCCPO_CHANGE_L: return "Change_L"; | ||
243 | case DCCPO_CONFIRM_L: return "Confirm_L"; | ||
244 | case DCCPO_CHANGE_R: return "Change_R"; | ||
245 | case DCCPO_CONFIRM_R: return "Confirm_R"; | ||
246 | } | ||
247 | return NULL; | ||
248 | } | ||
249 | |||
250 | static void dccp_feat_printval(u8 feat_num, dccp_feat_val const *val) | ||
251 | { | ||
252 | u8 i, type = dccp_feat_type(feat_num); | ||
253 | |||
254 | if (val == NULL || (type == FEAT_SP && val->sp.vec == NULL)) | ||
255 | dccp_pr_debug_cat("(NULL)"); | ||
256 | else if (type == FEAT_SP) | ||
257 | for (i = 0; i < val->sp.len; i++) | ||
258 | dccp_pr_debug_cat("%s%u", i ? " " : "", val->sp.vec[i]); | ||
259 | else if (type == FEAT_NN) | ||
260 | dccp_pr_debug_cat("%llu", (unsigned long long)val->nn); | ||
261 | else | ||
262 | dccp_pr_debug_cat("unknown type %u", type); | ||
263 | } | ||
264 | |||
265 | static void dccp_feat_printvals(u8 feat_num, u8 *list, u8 len) | ||
266 | { | ||
267 | u8 type = dccp_feat_type(feat_num); | ||
268 | dccp_feat_val fval = { .sp.vec = list, .sp.len = len }; | ||
269 | |||
270 | if (type == FEAT_NN) | ||
271 | fval.nn = dccp_decode_value_var(list, len); | ||
272 | dccp_feat_printval(feat_num, &fval); | ||
273 | } | ||
274 | |||
275 | static void dccp_feat_print_entry(struct dccp_feat_entry const *entry) | ||
276 | { | ||
277 | dccp_debug(" * %s %s = ", entry->is_local ? "local" : "remote", | ||
278 | dccp_feat_fname(entry->feat_num)); | ||
279 | dccp_feat_printval(entry->feat_num, &entry->val); | ||
280 | dccp_pr_debug_cat(", state=%s %s\n", dccp_feat_sname[entry->state], | ||
281 | entry->needs_confirm ? "(Confirm pending)" : ""); | ||
282 | } | ||
283 | |||
284 | #define dccp_feat_print_opt(opt, feat, val, len, mandatory) do { \ | ||
285 | dccp_pr_debug("%s(%s, ", dccp_feat_oname(opt), dccp_feat_fname(feat));\ | ||
286 | dccp_feat_printvals(feat, val, len); \ | ||
287 | dccp_pr_debug_cat(") %s\n", mandatory ? "!" : ""); } while (0) | ||
288 | |||
289 | #define dccp_feat_print_fnlist(fn_list) { \ | ||
290 | const struct dccp_feat_entry *___entry; \ | ||
291 | \ | ||
292 | dccp_pr_debug("List Dump:\n"); \ | ||
293 | list_for_each_entry(___entry, fn_list, node) \ | ||
294 | dccp_feat_print_entry(___entry); \ | ||
295 | } | ||
296 | #else /* ! CONFIG_IP_DCCP_DEBUG */ | ||
297 | #define dccp_feat_print_opt(opt, feat, val, len, mandatory) | ||
298 | #define dccp_feat_print_fnlist(fn_list) | ||
299 | #endif | ||
300 | |||
207 | static int __dccp_feat_activate(struct sock *sk, const int idx, | 301 | static int __dccp_feat_activate(struct sock *sk, const int idx, |
208 | const bool is_local, dccp_feat_val const *fval) | 302 | const bool is_local, dccp_feat_val const *fval) |
209 | { | 303 | { |
@@ -236,6 +330,10 @@ static int __dccp_feat_activate(struct sock *sk, const int idx, | |||
236 | /* Location is RX if this is a local-RX or remote-TX feature */ | 330 | /* Location is RX if this is a local-RX or remote-TX feature */ |
237 | rx = (is_local == (dccp_feat_table[idx].rxtx == FEAT_AT_RX)); | 331 | rx = (is_local == (dccp_feat_table[idx].rxtx == FEAT_AT_RX)); |
238 | 332 | ||
333 | dccp_debug(" -> activating %s %s, %sval=%llu\n", rx ? "RX" : "TX", | ||
334 | dccp_feat_fname(dccp_feat_table[idx].feat_num), | ||
335 | fval ? "" : "default ", (unsigned long long)val); | ||
336 | |||
239 | return dccp_feat_table[idx].activation_hdlr(sk, val, rx); | 337 | return dccp_feat_table[idx].activation_hdlr(sk, val, rx); |
240 | } | 338 | } |
241 | 339 | ||
@@ -539,6 +637,7 @@ int dccp_feat_insert_opts(struct dccp_sock *dp, struct dccp_request_sock *dreq, | |||
539 | return -1; | 637 | return -1; |
540 | } | 638 | } |
541 | } | 639 | } |
640 | dccp_feat_print_opt(opt, pos->feat_num, ptr, len, 0); | ||
542 | 641 | ||
543 | if (dccp_insert_fn_opt(skb, opt, pos->feat_num, ptr, len, rpt)) | 642 | if (dccp_insert_fn_opt(skb, opt, pos->feat_num, ptr, len, rpt)) |
544 | return -1; | 643 | return -1; |
@@ -792,6 +891,7 @@ int dccp_feat_finalise_settings(struct dccp_sock *dp) | |||
792 | while (i--) | 891 | while (i--) |
793 | if (ccids[i] > 0 && dccp_feat_propagate_ccid(fn, ccids[i], i)) | 892 | if (ccids[i] > 0 && dccp_feat_propagate_ccid(fn, ccids[i], i)) |
794 | return -1; | 893 | return -1; |
894 | dccp_feat_print_fnlist(fn); | ||
795 | return 0; | 895 | return 0; |
796 | } | 896 | } |
797 | 897 | ||
@@ -910,6 +1010,8 @@ static u8 dccp_feat_change_recv(struct list_head *fn, u8 is_mandatory, u8 opt, | |||
910 | if (len == 0 || type == FEAT_UNKNOWN) /* 6.1 and 6.6.8 */ | 1010 | if (len == 0 || type == FEAT_UNKNOWN) /* 6.1 and 6.6.8 */ |
911 | goto unknown_feature_or_value; | 1011 | goto unknown_feature_or_value; |
912 | 1012 | ||
1013 | dccp_feat_print_opt(opt, feat, val, len, is_mandatory); | ||
1014 | |||
913 | /* | 1015 | /* |
914 | * Negotiation of NN features: Change R is invalid, so there is no | 1016 | * Negotiation of NN features: Change R is invalid, so there is no |
915 | * simultaneous negotiation; hence we do not look up in the list. | 1017 | * simultaneous negotiation; hence we do not look up in the list. |
@@ -1015,6 +1117,8 @@ static u8 dccp_feat_confirm_recv(struct list_head *fn, u8 is_mandatory, u8 opt, | |||
1015 | const bool local = (opt == DCCPO_CONFIRM_R); | 1117 | const bool local = (opt == DCCPO_CONFIRM_R); |
1016 | struct dccp_feat_entry *entry = dccp_feat_list_lookup(fn, feat, local); | 1118 | struct dccp_feat_entry *entry = dccp_feat_list_lookup(fn, feat, local); |
1017 | 1119 | ||
1120 | dccp_feat_print_opt(opt, feat, val, len, is_mandatory); | ||
1121 | |||
1018 | if (entry == NULL) { /* nothing queued: ignore or handle error */ | 1122 | if (entry == NULL) { /* nothing queued: ignore or handle error */ |
1019 | if (is_mandatory && type == FEAT_UNKNOWN) | 1123 | if (is_mandatory && type == FEAT_UNKNOWN) |
1020 | return DCCP_RESET_CODE_MANDATORY_ERROR; | 1124 | return DCCP_RESET_CODE_MANDATORY_ERROR; |
@@ -1217,9 +1321,10 @@ int dccp_feat_activate_values(struct sock *sk, struct list_head *fn_list) | |||
1217 | goto activation_failed; | 1321 | goto activation_failed; |
1218 | } | 1322 | } |
1219 | if (cur->state != FEAT_STABLE) { | 1323 | if (cur->state != FEAT_STABLE) { |
1220 | DCCP_CRIT("Negotiation of %s %u failed in state %u", | 1324 | DCCP_CRIT("Negotiation of %s %s failed in state %s", |
1221 | cur->is_local ? "local" : "remote", | 1325 | cur->is_local ? "local" : "remote", |
1222 | cur->feat_num, cur->state); | 1326 | dccp_feat_fname(cur->feat_num), |
1327 | dccp_feat_sname[cur->state]); | ||
1223 | goto activation_failed; | 1328 | goto activation_failed; |
1224 | } | 1329 | } |
1225 | fvals[idx][cur->is_local] = &cur->val; | 1330 | fvals[idx][cur->is_local] = &cur->val; |
@@ -1260,47 +1365,3 @@ activation_failed: | |||
1260 | dp->dccps_hc_rx_ackvec = NULL; | 1365 | dp->dccps_hc_rx_ackvec = NULL; |
1261 | return -1; | 1366 | return -1; |
1262 | } | 1367 | } |
1263 | |||
1264 | #ifdef CONFIG_IP_DCCP_DEBUG | ||
1265 | const char *dccp_feat_typename(const u8 type) | ||
1266 | { | ||
1267 | switch(type) { | ||
1268 | case DCCPO_CHANGE_L: return("ChangeL"); | ||
1269 | case DCCPO_CONFIRM_L: return("ConfirmL"); | ||
1270 | case DCCPO_CHANGE_R: return("ChangeR"); | ||
1271 | case DCCPO_CONFIRM_R: return("ConfirmR"); | ||
1272 | /* the following case must not appear in feature negotation */ | ||
1273 | default: dccp_pr_debug("unknown type %d [BUG!]\n", type); | ||
1274 | } | ||
1275 | return NULL; | ||
1276 | } | ||
1277 | |||
1278 | EXPORT_SYMBOL_GPL(dccp_feat_typename); | ||
1279 | |||
1280 | const char *dccp_feat_name(const u8 feat) | ||
1281 | { | ||
1282 | static const char *feature_names[] = { | ||
1283 | [DCCPF_RESERVED] = "Reserved", | ||
1284 | [DCCPF_CCID] = "CCID", | ||
1285 | [DCCPF_SHORT_SEQNOS] = "Allow Short Seqnos", | ||
1286 | [DCCPF_SEQUENCE_WINDOW] = "Sequence Window", | ||
1287 | [DCCPF_ECN_INCAPABLE] = "ECN Incapable", | ||
1288 | [DCCPF_ACK_RATIO] = "Ack Ratio", | ||
1289 | [DCCPF_SEND_ACK_VECTOR] = "Send ACK Vector", | ||
1290 | [DCCPF_SEND_NDP_COUNT] = "Send NDP Count", | ||
1291 | [DCCPF_MIN_CSUM_COVER] = "Min. Csum Coverage", | ||
1292 | [DCCPF_DATA_CHECKSUM] = "Send Data Checksum", | ||
1293 | }; | ||
1294 | if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC) | ||
1295 | return feature_names[DCCPF_RESERVED]; | ||
1296 | |||
1297 | if (feat == DCCPF_SEND_LEV_RATE) | ||
1298 | return "Send Loss Event Rate"; | ||
1299 | if (feat >= DCCPF_MIN_CCID_SPECIFIC) | ||
1300 | return "CCID-specific"; | ||
1301 | |||
1302 | return feature_names[feat]; | ||
1303 | } | ||
1304 | |||
1305 | EXPORT_SYMBOL_GPL(dccp_feat_name); | ||
1306 | #endif /* CONFIG_IP_DCCP_DEBUG */ | ||
diff --git a/net/dccp/feat.h b/net/dccp/feat.h index f8456bca4eeb..2217066e22d7 100644 --- a/net/dccp/feat.h +++ b/net/dccp/feat.h | |||
@@ -106,19 +106,6 @@ extern unsigned long sysctl_dccp_sequence_window; | |||
106 | extern int sysctl_dccp_rx_ccid; | 106 | extern int sysctl_dccp_rx_ccid; |
107 | extern int sysctl_dccp_tx_ccid; | 107 | extern int sysctl_dccp_tx_ccid; |
108 | 108 | ||
109 | #ifdef CONFIG_IP_DCCP_DEBUG | ||
110 | extern const char *dccp_feat_typename(const u8 type); | ||
111 | extern const char *dccp_feat_name(const u8 feat); | ||
112 | |||
113 | static inline void dccp_feat_debug(const u8 type, const u8 feat, const u8 val) | ||
114 | { | ||
115 | dccp_pr_debug("%s(%s (%d), %d)\n", dccp_feat_typename(type), | ||
116 | dccp_feat_name(feat), feat, val); | ||
117 | } | ||
118 | #else | ||
119 | #define dccp_feat_debug(type, feat, val) | ||
120 | #endif /* CONFIG_IP_DCCP_DEBUG */ | ||
121 | |||
122 | extern int dccp_feat_init(struct sock *sk); | 109 | extern int dccp_feat_init(struct sock *sk); |
123 | extern void dccp_feat_initialise_sysctls(void); | 110 | extern void dccp_feat_initialise_sysctls(void); |
124 | extern int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local, | 111 | extern int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local, |
diff --git a/net/dccp/options.c b/net/dccp/options.c index 5906e96eedde..fd51cc70c63e 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
@@ -498,10 +498,6 @@ int dccp_insert_fn_opt(struct sk_buff *skb, u8 type, u8 feat, | |||
498 | *to++ = *val; | 498 | *to++ = *val; |
499 | if (len) | 499 | if (len) |
500 | memcpy(to, val, len); | 500 | memcpy(to, val, len); |
501 | |||
502 | dccp_pr_debug("%s(%s (%d), ...), length %d\n", | ||
503 | dccp_feat_typename(type), | ||
504 | dccp_feat_name(feat), feat, len); | ||
505 | return 0; | 501 | return 0; |
506 | } | 502 | } |
507 | 503 | ||