Em Wed, Jan 07, 2009 at 12:27:22PM +0800, shizibo escreveu: > Hello, I am just studying the codes of DCCP, I encounter some > questions now. I send this mail to <dccp@xxxxxxxxxxxxxxx>, but the > yahoo mail box inform me that it can not be delivered.So sorry to > bother you.Will you help me. No problem, I'm replying to you and to the list, so that the answers can help others in the future. > in dccp_connect(): > skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation); > where is the sk->sk_prot->max_header set before it's used here? Use grep: [acme@doppio linux-2.6]$ grep "max_header.\+=" net/dccp/*.c net/dccp/ipv4.c: .max_header = MAX_DCCP_HEADER, net/dccp/ipv6.c: .max_header = MAX_DCCP_HEADER, [acme@doppio linux-2.6]$ I.e. it depends on the layer 3 used. Now look at net/dccp/ipv4.c to see exactly how it is initialized: static struct proto dccp_v4_prot = { <SNIP> .max_header = MAX_DCCP_HEADER, <SNIP> }; And this, in turn, is referenced here: static struct inet_protosw dccp_v4_protosw = { .type = SOCK_DCCP, .protocol = IPPROTO_DCCP, .prot = &dccp_v4_prot, .ops = &inet_dccp_ops, .capability = -1, .no_check = 0, .flags = INET_PROTOSW_ICSK, }; If you now search where dccp_v4_protosw is used: static int __init dccp_v4_init(void) <SNIP> inet_register_protosw(&dccp_v4_protosw); <SNIP> } inet_register_protosw will let net/ipv4/af_inet.c that when a PF_INET socket of type SOCK_DCCP is asked for we should use dccp_v4_prot, etc. Please take a look at a paper a wrote that explains these details: http://ols.fedoraproject.org/OLS/Reprints-2005/melo-Reprint.pdf Look at chapter 3. > and, there is macro: > #define DCCP_SKB_CB(__skb) ((struct dccp_skb_cb *)&((__skb)->cb[0])) > It is said the skb->cb is used to hold some private control message > per layer. For dccp, where is it initialized? What does the other > bytes, cb[1], cb[2]..., content? This is a scratch pad, always casted to some struct that is layer specific, for instance, for DCCP, it is 'struct dccp_skb_cb', that is defined in net/dccp/dccp.h: /** * dccp_skb_cb - DCCP per-packet control information * @dccpd_type: one of %dccp_pkt_type (or unknown) * @dccpd_ccval: CCVal field (5.1), see e.g. RFC 4342, 8.1 * @dccpd_reset_code: one of %dccp_reset_codes * @dccpd_reset_data: Data1..3 fields (depend on @dccpd_reset_code) * @dccpd_opt_len: total length of all options (5.8) in the packet * @dccpd_seq: sequence number * @dccpd_ack_seq: acknowledgment number subheader field value * This is used for transmission as well as for reception. */ struct dccp_skb_cb { union { struct inet_skb_parm h4; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) struct inet6_skb_parm h6; #endif } header; __u8 dccpd_type:4; __u8 dccpd_ccval:4; __u8 dccpd_reset_code, dccpd_reset_data[3]; __u16 dccpd_opt_len; __u64 dccpd_seq; __u64 dccpd_ack_seq; }; So we don't access, say, skb->cb[5], but instead we cast it to a variable (or use it directly as DCCP_SKB_CB(skb)->dccpd_type), like in dccp_v4_rcv in net/dccp/ipv4.c: static int dccp_v4_rcv(struct sk_buff *skb) { const struct dccp_hdr *dh; <SNIP> dh = dccp_hdr(skb); DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh); DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; <SNIP> So, in this case, it is initialized when we receive a packet. Later, in the same function (dccp_v4_rcv), if we don't find a socket to queue this packet into, we use the skb->cb area in another fashion, this time setting dccpd_reset_code to the sensible value and calling a routine (dccp_v4_ctl_send_reset) that will then get this value and do something it it: no_dccp_socket: if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) goto discard_it; /* * Step 2: * If no socket ... * Generate Reset(No Connection) unless P.type == * Reset * Drop packet and return */ if (dh->dccph_type != DCCP_PKT_RESET) { DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_NO_CONNECTION; dccp_v4_ctl_send_reset(sk, skb); } - Arnaldo -- To unsubscribe from this list: send the line "unsubscribe dccp" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html