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 /net/dccp | |
| 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>
Diffstat (limited to 'net/dccp')
| -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 4f681f1a16c..94ae6d41d72 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 4c95cbdb0e0..3abacad0b22 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 f8456bca4ee..2217066e22d 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 5906e96eedd..fd51cc70c63 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 | ||
