* [PATCH 2/7] [DCCP]: Move dccp_v4_{init,destroy}_sock to the core
From: Arnaldo Carvalho de Melo @ 2006-02-23 22:12 UTC (permalink / raw)
To: dccp
Removing one more ipv6 uses ipv4 stuff case in dccp land.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
net/dccp/dccp.h | 4 +-
net/dccp/ipv4.c | 106 +++---------------------------------------------------
net/dccp/ipv6.c | 4 +-
net/dccp/proto.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 112 insertions(+), 104 deletions(-)
8f62e07749b62f28242dc9fb7db5c0531d33401e
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index cd7c5d0..8f3903b 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -228,8 +228,8 @@ extern int dccp_rcv_state_process(struct
extern int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
const struct dccp_hdr *dh, const unsigned len);
-extern int dccp_v4_init_sock(struct sock *sk);
-extern int dccp_v4_destroy_sock(struct sock *sk);
+extern int dccp_init_sock(struct sock *sk);
+extern int dccp_destroy_sock(struct sock *sk);
extern void dccp_close(struct sock *sk, long timeout);
extern struct sk_buff *dccp_make_response(struct sock *sk,
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 766b619..b26a4f8 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1008,109 +1008,15 @@ struct inet_connection_sock_af_ops dccp_
.sockaddr_len = sizeof(struct sockaddr_in),
};
-int dccp_v4_init_sock(struct sock *sk)
+static int dccp_v4_init_sock(struct sock *sk)
{
- struct dccp_sock *dp = dccp_sk(sk);
- struct inet_connection_sock *icsk = inet_csk(sk);
- static int dccp_ctl_socket_init = 1;
-
- dccp_options_init(&dp->dccps_options);
- do_gettimeofday(&dp->dccps_epoch);
-
- /*
- * FIXME: We're hardcoding the CCID, and doing this at this point makes
- * the listening (master) sock get CCID control blocks, which is not
- * necessary, but for now, to not mess with the test userspace apps,
- * lets leave it here, later the real solution is to do this in a
- * setsockopt(CCIDs-I-want/accept). -acme
- */
- if (likely(!dccp_ctl_socket_init)) {
- int rc = dccp_feat_init(sk);
-
- if (rc)
- return rc;
-
- if (dp->dccps_options.dccpo_send_ack_vector) {
- dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(GFP_KERNEL);
- if (dp->dccps_hc_rx_ackvec = NULL)
- return -ENOMEM;
- }
- dp->dccps_hc_rx_ccid - ccid_hc_rx_new(dp->dccps_options.dccpo_rx_ccid,
- sk, GFP_KERNEL);
- dp->dccps_hc_tx_ccid - ccid_hc_tx_new(dp->dccps_options.dccpo_tx_ccid,
- sk, GFP_KERNEL);
- if (unlikely(dp->dccps_hc_rx_ccid = NULL ||
- dp->dccps_hc_tx_ccid = NULL)) {
- ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
- ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
- if (dp->dccps_options.dccpo_send_ack_vector) {
- dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
- dp->dccps_hc_rx_ackvec = NULL;
- }
- dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
- return -ENOMEM;
- }
- } else {
- /* control socket doesn't need feat nego */
- INIT_LIST_HEAD(&dp->dccps_options.dccpo_pending);
- INIT_LIST_HEAD(&dp->dccps_options.dccpo_conf);
- dccp_ctl_socket_init = 0;
- }
-
- dccp_init_xmit_timers(sk);
- icsk->icsk_rto = DCCP_TIMEOUT_INIT;
- sk->sk_state = DCCP_CLOSED;
- sk->sk_write_space = dccp_write_space;
- icsk->icsk_af_ops = &dccp_ipv4_af_ops;
- icsk->icsk_sync_mss = dccp_sync_mss;
- dp->dccps_mss_cache = 536;
- dp->dccps_role = DCCP_ROLE_UNDEFINED;
- dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
- dp->dccps_l_ack_ratio = dp->dccps_r_ack_ratio = 1;
+ const int err = dccp_init_sock(sk);
- return 0;
+ if (err = 0)
+ inet_csk(sk)->icsk_af_ops = &dccp_ipv4_af_ops;
+ return err;
}
-EXPORT_SYMBOL_GPL(dccp_v4_init_sock);
-
-int dccp_v4_destroy_sock(struct sock *sk)
-{
- struct dccp_sock *dp = dccp_sk(sk);
-
- /*
- * DCCP doesn't use sk_write_queue, just sk_send_head
- * for retransmissions
- */
- if (sk->sk_send_head != NULL) {
- kfree_skb(sk->sk_send_head);
- sk->sk_send_head = NULL;
- }
-
- /* Clean up a referenced DCCP bind bucket. */
- if (inet_csk(sk)->icsk_bind_hash != NULL)
- inet_put_port(&dccp_hashinfo, sk);
-
- kfree(dp->dccps_service_list);
- dp->dccps_service_list = NULL;
-
- if (dp->dccps_options.dccpo_send_ack_vector) {
- dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
- dp->dccps_hc_rx_ackvec = NULL;
- }
- ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
- ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
- dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
-
- /* clean up feature negotiation state */
- dccp_feat_clean(sk);
-
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(dccp_v4_destroy_sock);
-
static void dccp_v4_reqsk_destructor(struct request_sock *req)
{
kfree(inet_rsk(req)->opt);
@@ -1147,7 +1053,7 @@ struct proto dccp_prot = {
.accept = inet_csk_accept,
.get_port = dccp_v4_get_port,
.shutdown = dccp_shutdown,
- .destroy = dccp_v4_destroy_sock,
+ .destroy = dccp_destroy_sock,
.orphan_count = &dccp_orphan_count,
.max_header = MAX_DCCP_HEADER,
.obj_size = sizeof(struct dccp_sock),
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index ad5a1c6..84651bc 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1146,7 +1146,7 @@ static struct inet_connection_sock_af_op
*/
static int dccp_v6_init_sock(struct sock *sk)
{
- int err = dccp_v4_init_sock(sk);
+ int err = dccp_init_sock(sk);
if (err = 0)
inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
@@ -1156,7 +1156,7 @@ static int dccp_v6_init_sock(struct sock
static int dccp_v6_destroy_sock(struct sock *sk)
{
- dccp_v4_destroy_sock(sk);
+ dccp_destroy_sock(sk);
return inet6_destroy_sock(sk);
}
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 04315c3..1f5c92d 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -97,6 +97,108 @@ const char *dccp_state_name(const int st
EXPORT_SYMBOL_GPL(dccp_state_name);
+int dccp_init_sock(struct sock *sk)
+{
+ struct dccp_sock *dp = dccp_sk(sk);
+ struct inet_connection_sock *icsk = inet_csk(sk);
+ static int dccp_ctl_socket_init = 1;
+
+ dccp_options_init(&dp->dccps_options);
+ do_gettimeofday(&dp->dccps_epoch);
+
+ /*
+ * FIXME: We're hardcoding the CCID, and doing this at this point makes
+ * the listening (master) sock get CCID control blocks, which is not
+ * necessary, but for now, to not mess with the test userspace apps,
+ * lets leave it here, later the real solution is to do this in a
+ * setsockopt(CCIDs-I-want/accept). -acme
+ */
+ if (likely(!dccp_ctl_socket_init)) {
+ int rc = dccp_feat_init(sk);
+
+ if (rc)
+ return rc;
+
+ if (dp->dccps_options.dccpo_send_ack_vector) {
+ dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(GFP_KERNEL);
+ if (dp->dccps_hc_rx_ackvec = NULL)
+ return -ENOMEM;
+ }
+ dp->dccps_hc_rx_ccid + ccid_hc_rx_new(dp->dccps_options.dccpo_rx_ccid,
+ sk, GFP_KERNEL);
+ dp->dccps_hc_tx_ccid + ccid_hc_tx_new(dp->dccps_options.dccpo_tx_ccid,
+ sk, GFP_KERNEL);
+ if (unlikely(dp->dccps_hc_rx_ccid = NULL ||
+ dp->dccps_hc_tx_ccid = NULL)) {
+ ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
+ ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
+ if (dp->dccps_options.dccpo_send_ack_vector) {
+ dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
+ dp->dccps_hc_rx_ackvec = NULL;
+ }
+ dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
+ return -ENOMEM;
+ }
+ } else {
+ /* control socket doesn't need feat nego */
+ INIT_LIST_HEAD(&dp->dccps_options.dccpo_pending);
+ INIT_LIST_HEAD(&dp->dccps_options.dccpo_conf);
+ dccp_ctl_socket_init = 0;
+ }
+
+ dccp_init_xmit_timers(sk);
+ icsk->icsk_rto = DCCP_TIMEOUT_INIT;
+ sk->sk_state = DCCP_CLOSED;
+ sk->sk_write_space = dccp_write_space;
+ icsk->icsk_sync_mss = dccp_sync_mss;
+ dp->dccps_mss_cache = 536;
+ dp->dccps_role = DCCP_ROLE_UNDEFINED;
+ dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
+ dp->dccps_l_ack_ratio = dp->dccps_r_ack_ratio = 1;
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(dccp_init_sock);
+
+int dccp_destroy_sock(struct sock *sk)
+{
+ struct dccp_sock *dp = dccp_sk(sk);
+
+ /*
+ * DCCP doesn't use sk_write_queue, just sk_send_head
+ * for retransmissions
+ */
+ if (sk->sk_send_head != NULL) {
+ kfree_skb(sk->sk_send_head);
+ sk->sk_send_head = NULL;
+ }
+
+ /* Clean up a referenced DCCP bind bucket. */
+ if (inet_csk(sk)->icsk_bind_hash != NULL)
+ inet_put_port(&dccp_hashinfo, sk);
+
+ kfree(dp->dccps_service_list);
+ dp->dccps_service_list = NULL;
+
+ if (dp->dccps_options.dccpo_send_ack_vector) {
+ dccp_ackvec_free(dp->dccps_hc_rx_ackvec);
+ dp->dccps_hc_rx_ackvec = NULL;
+ }
+ ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
+ ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
+ dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
+
+ /* clean up feature negotiation state */
+ dccp_feat_clean(sk);
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(dccp_destroy_sock);
+
static inline int dccp_listen_start(struct sock *sk)
{
struct dccp_sock *dp = dccp_sk(sk);
--
1.2.2.gd27d
^ permalink raw reply related
* [PATCH 7/7] [DCCP]: Move the IPv4 specific bits from proto.c to ipv4.c
From: Arnaldo Carvalho de Melo @ 2006-02-23 22:12 UTC (permalink / raw)
To: dccp
With this patch in place we can break down the complexity by better
compartmentalizing the code that is common to ipv6 and ipv4.
Now we have these modules:
Module Size Used by
dccp_diag 1344 0
inet_diag 9448 1 dccp_diag
dccp_ccid3 15856 0
dccp_tfrc_lib 12320 1 dccp_ccid3
dccp_ccid2 5764 0
dccp_ipv4 16996 2
dccp 48208 4 dccp_diag,dccp_ccid3,dccp_ccid2,dccp_ipv4
dccp_ipv6 still requires dccp_ipv4 due to dccp_ipv6_mapped, that is the next
target to work on the "hey, ipv4 is legacy, I only want ipv6 dude!" direction.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
net/dccp/Makefile | 7 +--
net/dccp/dccp.h | 6 --
net/dccp/ipv4.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++--
net/dccp/options.c | 2 +
net/dccp/output.c | 2 +
net/dccp/proto.c | 132 ++-----------------------------------------------
6 files changed, 148 insertions(+), 141 deletions(-)
63d1742ba27197d1678bd5cc05cfa8a1fde3c6d4
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index 7af0569..7696e21 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -2,10 +2,11 @@ obj-$(CONFIG_IPV6) += dccp_ipv6.o
dccp_ipv6-y := ipv6.o
-obj-$(CONFIG_IP_DCCP) += dccp.o
+obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv4.o
-dccp-y := ccid.o feat.o input.o ipv4.o minisocks.o options.o output.o proto.o \
- timer.o
+dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o
+
+dccp_ipv4-y := ipv4.o
dccp-$(CONFIG_IP_DCCP_ACKVEC) += ackvec.o
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index b6ea4cc..46aa481 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -59,8 +59,6 @@ extern void dccp_time_wait(struct sock *
#define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */
-extern struct proto dccp_prot;
-
/* is seq1 < seq2 ? */
static inline int before48(const u64 seq1, const u64 seq2)
{
@@ -209,10 +207,6 @@ extern struct sock *dccp_create_openreq_
extern int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb);
-extern void dccp_v4_err(struct sk_buff *skb, u32);
-
-extern int dccp_v4_rcv(struct sk_buff *skb);
-
extern struct sock *dccp_v4_request_recv_sock(struct sock *sk,
struct sk_buff *skb,
struct request_sock *req,
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index a7332f0..033c3ab 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -18,8 +18,10 @@
#include <linux/random.h>
#include <net/icmp.h>
+#include <net/inet_common.h>
#include <net/inet_hashtables.h>
#include <net/inet_sock.h>
+#include <net/protocol.h>
#include <net/sock.h>
#include <net/timewait_sock.h>
#include <net/tcp_states.h>
@@ -285,7 +287,7 @@ out:
* check at all. A more general error queue to queue errors for later handling
* is probably better.
*/
-void dccp_v4_err(struct sk_buff *skb, u32 info)
+static void dccp_v4_err(struct sk_buff *skb, u32 info)
{
const struct iphdr *iph = (struct iphdr *)skb->data;
const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data +
@@ -639,6 +641,8 @@ int dccp_v4_checksum(const struct sk_buf
IPPROTO_DCCP, tmp);
}
+EXPORT_SYMBOL_GPL(dccp_v4_checksum);
+
static int dccp_v4_verify_checksum(struct sk_buff *skb,
const __be32 saddr, const __be32 daddr)
{
@@ -871,7 +875,7 @@ int dccp_invalid_packet(struct sk_buff *
EXPORT_SYMBOL_GPL(dccp_invalid_packet);
/* this is called when real data arrives */
-int dccp_v4_rcv(struct sk_buff *skb)
+static int dccp_v4_rcv(struct sk_buff *skb)
{
const struct dccp_hdr *dh;
struct sock *sk;
@@ -978,7 +982,7 @@ do_time_wait:
goto no_dccp_socket;
}
-struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
+static struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
.queue_xmit = ip_queue_xmit,
.send_check = dccp_v4_send_check,
.rebuild_header = inet_sk_rebuild_header,
@@ -1018,7 +1022,7 @@ static struct timewait_sock_ops dccp_tim
.twsk_obj_size = sizeof(struct inet_timewait_sock),
};
-struct proto dccp_prot = {
+struct proto dccp_v4_prot = {
.name = "DCCP",
.owner = THIS_MODULE,
.close = dccp_close,
@@ -1044,4 +1048,130 @@ struct proto dccp_prot = {
.twsk_prot = &dccp_timewait_sock_ops,
};
-EXPORT_SYMBOL_GPL(dccp_prot);
+static struct net_protocol dccp_v4_protocol = {
+ .handler = dccp_v4_rcv,
+ .err_handler = dccp_v4_err,
+ .no_policy = 1,
+};
+
+static const struct proto_ops inet_dccp_ops = {
+ .family = PF_INET,
+ .owner = THIS_MODULE,
+ .release = inet_release,
+ .bind = inet_bind,
+ .connect = inet_stream_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = inet_accept,
+ .getname = inet_getname,
+ /* FIXME: work on tcp_poll to rename it to inet_csk_poll */
+ .poll = dccp_poll,
+ .ioctl = inet_ioctl,
+ /* FIXME: work on inet_listen to rename it to sock_common_listen */
+ .listen = inet_dccp_listen,
+ .shutdown = inet_shutdown,
+ .setsockopt = sock_common_setsockopt,
+ .getsockopt = sock_common_getsockopt,
+ .sendmsg = inet_sendmsg,
+ .recvmsg = sock_common_recvmsg,
+ .mmap = sock_no_mmap,
+ .sendpage = sock_no_sendpage,
+};
+
+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,
+};
+
+/*
+ * This is the global socket data structure used for responding to
+ * the Out-of-the-blue (OOTB) packets. A control sock will be created
+ * for this socket at the initialization time.
+ */
+struct socket *dccp_ctl_socket;
+
+static char dccp_ctl_socket_err_msg[] __initdata + KERN_ERR "DCCP: Failed to create the control socket.\n";
+
+static int __init dccp_ctl_sock_init(void)
+{
+ int rc = sock_create_kern(PF_INET, SOCK_DCCP, IPPROTO_DCCP,
+ &dccp_ctl_socket);
+ if (rc < 0)
+ printk(dccp_ctl_socket_err_msg);
+ else {
+ dccp_ctl_socket->sk->sk_allocation = GFP_ATOMIC;
+ inet_sk(dccp_ctl_socket->sk)->uc_ttl = -1;
+
+ /* Unhash it so that IP input processing does not even
+ * see it, we do not wish this socket to see incoming
+ * packets.
+ */
+ dccp_ctl_socket->sk->sk_prot->unhash(dccp_ctl_socket->sk);
+ }
+
+ return rc;
+}
+
+#ifdef CONFIG_IP_DCCP_UNLOAD_HACK
+void dccp_ctl_sock_exit(void)
+{
+ if (dccp_ctl_socket != NULL) {
+ sock_release(dccp_ctl_socket);
+ dccp_ctl_socket = NULL;
+ }
+}
+
+EXPORT_SYMBOL_GPL(dccp_ctl_sock_exit);
+#endif
+
+static int __init dccp_v4_init(void)
+{
+ int err = proto_register(&dccp_v4_prot, 1);
+
+ if (err != 0)
+ goto out;
+
+ err = inet_add_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
+ if (err != 0)
+ goto out_proto_unregister;
+
+ inet_register_protosw(&dccp_v4_protosw);
+
+ err = dccp_ctl_sock_init();
+ if (err)
+ goto out_unregister_protosw;
+out:
+ return err;
+out_unregister_protosw:
+ inet_unregister_protosw(&dccp_v4_protosw);
+ inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
+out_proto_unregister:
+ proto_unregister(&dccp_v4_prot);
+ goto out;
+}
+
+static void __exit dccp_v4_exit(void)
+{
+ inet_unregister_protosw(&dccp_v4_protosw);
+ inet_del_protocol(&dccp_v4_protocol, IPPROTO_DCCP);
+ proto_unregister(&dccp_v4_prot);
+}
+
+module_init(dccp_v4_init);
+module_exit(dccp_v4_exit);
+
+/*
+ * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
+ * values directly, Also cover the case where the protocol is not specified,
+ * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP
+ */
+MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-33-type-6");
+MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-0-type-6");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
+MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 3ecd319..79d228e 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -258,6 +258,8 @@ out_invalid_option:
return -1;
}
+EXPORT_SYMBOL_GPL(dccp_parse_options);
+
static void dccp_encode_value_var(const u32 value, unsigned char *to,
const unsigned int len)
{
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 6bd21e3..8c83aa5 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -526,6 +526,8 @@ void dccp_send_sync(struct sock *sk, con
dccp_transmit_skb(sk, skb);
}
+EXPORT_SYMBOL_GPL(dccp_send_sync);
+
/*
* Send a DCCP_PKT_CLOSE/CLOSEREQ. The caller locks the socket for us. This
* cannot be allowed to fail queueing a DCCP_PKT_CLOSE/CLOSEREQ frame under
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index c048d5b..d110cdb 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -23,9 +23,7 @@
#include <linux/random.h>
#include <net/checksum.h>
-#include <net/inet_common.h>
#include <net/inet_sock.h>
-#include <net/protocol.h>
#include <net/sock.h>
#include <net/xfrm.h>
@@ -55,12 +53,6 @@ struct inet_hashinfo __cacheline_aligned
EXPORT_SYMBOL_GPL(dccp_hashinfo);
-static struct net_protocol dccp_protocol = {
- .handler = dccp_v4_rcv,
- .err_handler = dccp_v4_err,
- .no_policy = 1,
-};
-
const char *dccp_packet_name(const int type)
{
static const char *dccp_packet_names[] = {
@@ -856,83 +848,6 @@ void dccp_shutdown(struct sock *sk, int
EXPORT_SYMBOL_GPL(dccp_shutdown);
-static const struct proto_ops inet_dccp_ops = {
- .family = PF_INET,
- .owner = THIS_MODULE,
- .release = inet_release,
- .bind = inet_bind,
- .connect = inet_stream_connect,
- .socketpair = sock_no_socketpair,
- .accept = inet_accept,
- .getname = inet_getname,
- /* FIXME: work on tcp_poll to rename it to inet_csk_poll */
- .poll = dccp_poll,
- .ioctl = inet_ioctl,
- /* FIXME: work on inet_listen to rename it to sock_common_listen */
- .listen = inet_dccp_listen,
- .shutdown = inet_shutdown,
- .setsockopt = sock_common_setsockopt,
- .getsockopt = sock_common_getsockopt,
- .sendmsg = inet_sendmsg,
- .recvmsg = sock_common_recvmsg,
- .mmap = sock_no_mmap,
- .sendpage = sock_no_sendpage,
-};
-
-extern struct net_proto_family inet_family_ops;
-
-static struct inet_protosw dccp_v4_protosw = {
- .type = SOCK_DCCP,
- .protocol = IPPROTO_DCCP,
- .prot = &dccp_prot,
- .ops = &inet_dccp_ops,
- .capability = -1,
- .no_check = 0,
- .flags = INET_PROTOSW_ICSK,
-};
-
-/*
- * This is the global socket data structure used for responding to
- * the Out-of-the-blue (OOTB) packets. A control sock will be created
- * for this socket at the initialization time.
- */
-struct socket *dccp_ctl_socket;
-
-static char dccp_ctl_socket_err_msg[] __initdata - KERN_ERR "DCCP: Failed to create the control socket.\n";
-
-static int __init dccp_ctl_sock_init(void)
-{
- int rc = sock_create_kern(PF_INET, SOCK_DCCP, IPPROTO_DCCP,
- &dccp_ctl_socket);
- if (rc < 0)
- printk(dccp_ctl_socket_err_msg);
- else {
- dccp_ctl_socket->sk->sk_allocation = GFP_ATOMIC;
- inet_sk(dccp_ctl_socket->sk)->uc_ttl = -1;
-
- /* Unhash it so that IP input processing does not even
- * see it, we do not wish this socket to see incoming
- * packets.
- */
- dccp_ctl_socket->sk->sk_prot->unhash(dccp_ctl_socket->sk);
- }
-
- return rc;
-}
-
-#ifdef CONFIG_IP_DCCP_UNLOAD_HACK
-void dccp_ctl_sock_exit(void)
-{
- if (dccp_ctl_socket != NULL) {
- sock_release(dccp_ctl_socket);
- dccp_ctl_socket = NULL;
- }
-}
-
-EXPORT_SYMBOL_GPL(dccp_ctl_sock_exit);
-#endif
-
static int __init dccp_mib_init(void)
{
int rc = -ENOMEM;
@@ -955,7 +870,7 @@ out_free_one:
}
-static int dccp_mib_exit(void)
+static void dccp_mib_exit(void)
{
free_percpu(dccp_statistics[0]);
free_percpu(dccp_statistics[1]);
@@ -978,18 +893,14 @@ static int __init dccp_init(void)
{
unsigned long goal;
int ehash_order, bhash_order, i;
- int rc = proto_register(&dccp_prot, 1);
+ int rc = -ENOBUFS;
- if (rc)
- goto out;
-
- rc = -ENOBUFS;
dccp_hashinfo.bind_bucket_cachep kmem_cache_create("dccp_bind_bucket",
sizeof(struct inet_bind_bucket), 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!dccp_hashinfo.bind_bucket_cachep)
- goto out_proto_unregister;
+ goto out;
/*
* Size and allocate the main established and bind bucket
@@ -1055,33 +966,18 @@ static int __init dccp_init(void)
if (rc)
goto out_free_dccp_bhash;
- rc = -EAGAIN;
- if (inet_add_protocol(&dccp_protocol, IPPROTO_DCCP))
- goto out_free_dccp_v4_mibs;
-
- inet_register_protosw(&dccp_v4_protosw);
-
rc = dccp_ackvec_init();
if (rc)
- goto out_unregister_protosw;
+ goto out_free_dccp_mib;
rc = dccp_sysctl_init();
if (rc)
goto out_ackvec_exit;
-
- rc = dccp_ctl_sock_init();
- if (rc)
- goto out_sysctl_exit;
out:
return rc;
-out_sysctl_exit:
- dccp_sysctl_exit();
out_ackvec_exit:
dccp_ackvec_exit();
-out_unregister_protosw:
- inet_unregister_protosw(&dccp_v4_protosw);
- inet_del_protocol(&dccp_protocol, IPPROTO_DCCP);
-out_free_dccp_v4_mibs:
+out_free_dccp_mib:
dccp_mib_exit();
out_free_dccp_bhash:
free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
@@ -1092,21 +988,11 @@ out_free_dccp_ehash:
out_free_bind_bucket_cachep:
kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
dccp_hashinfo.bind_bucket_cachep = NULL;
-out_proto_unregister:
- proto_unregister(&dccp_prot);
goto out;
}
-static const char dccp_del_proto_err_msg[] __exitdata - KERN_ERR "can't remove dccp net_protocol\n";
-
static void __exit dccp_fini(void)
{
- inet_unregister_protosw(&dccp_v4_protosw);
-
- if (inet_del_protocol(&dccp_protocol, IPPROTO_DCCP) < 0)
- printk(dccp_del_proto_err_msg);
-
dccp_mib_exit();
free_pages((unsigned long)dccp_hashinfo.bhash,
get_order(dccp_hashinfo.bhash_size *
@@ -1115,7 +1001,6 @@ static void __exit dccp_fini(void)
get_order(dccp_hashinfo.ehash_size *
sizeof(struct inet_ehash_bucket)));
kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
- proto_unregister(&dccp_prot);
dccp_ackvec_exit();
dccp_sysctl_exit();
}
@@ -1123,13 +1008,6 @@ static void __exit dccp_fini(void)
module_init(dccp_init);
module_exit(dccp_fini);
-/*
- * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
- * values directly, Also cover the case where the protocol is not specified,
- * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP
- */
-MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-33-type-6");
-MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-0-type-6");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@conectiva.com.br>");
MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");
--
1.2.2.gd27d
^ permalink raw reply related
* [PATCH 4/7] [DCCP]: Dont use dccp_v4_checksum in dccp_make_response
From: Arnaldo Carvalho de Melo @ 2006-02-23 22:12 UTC (permalink / raw)
To: dccp
dccp_make_response is shared by ipv4/6 and the ipv6 code was recalculating the
checksum, not good, so move the dccp_v4_checksum call to dccp_v4_send_response.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
net/dccp/ipv4.c | 3 +++
net/dccp/output.c | 3 ---
2 files changed, 3 insertions(+), 3 deletions(-)
e9ec1a839d3fe9f2ec5e864a094cf04b6c511c03
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 34d1b11..f087593 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -264,7 +264,10 @@ static int dccp_v4_send_response(struct
skb = dccp_make_response(sk, dst, req);
if (skb != NULL) {
const struct inet_request_sock *ireq = inet_rsk(req);
+ struct dccp_hdr *dh = dccp_hdr(skb);
+ dh->dccph_checksum = dccp_v4_checksum(skb, ireq->loc_addr,
+ ireq->rmt_addr);
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
ireq->rmt_addr,
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 9922d26..6bd21e3 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -314,9 +314,6 @@ struct sk_buff *dccp_make_response(struc
dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr);
dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;
- dh->dccph_checksum = dccp_v4_checksum(skb, inet_rsk(req)->loc_addr,
- inet_rsk(req)->rmt_addr);
-
DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
return skb;
}
--
1.2.2.gd27d
^ permalink raw reply related
* [PATCH 1/7] [DCCP]: Generalize dccp_v4_send_reset
From: Arnaldo Carvalho de Melo @ 2006-02-23 22:12 UTC (permalink / raw)
To: dccp
Renaming it to dccp_send_reset and moving it from the ipv4 specific code to the
core dccp code.
This fixes some bugs in IPV6 where timers would send v4 resets, etc.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
net/dccp/dccp.h | 6 +-----
net/dccp/input.c | 2 +-
net/dccp/ipv4.c | 26 --------------------------
net/dccp/output.c | 30 +++++++++++++++++++++++++-----
net/dccp/timer.c | 2 +-
5 files changed, 28 insertions(+), 38 deletions(-)
f6d02dcee746dd116bcdf3902d40eeab21e3b517
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index f059541..cd7c5d0 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -235,9 +235,6 @@ extern void dccp_close(struct sock *sk,
extern struct sk_buff *dccp_make_response(struct sock *sk,
struct dst_entry *dst,
struct request_sock *req);
-extern struct sk_buff *dccp_make_reset(struct sock *sk,
- struct dst_entry *dst,
- enum dccp_reset_codes code);
extern int dccp_connect(struct sock *sk);
extern int dccp_disconnect(struct sock *sk, int flags);
@@ -264,8 +261,7 @@ extern int dccp_v4_connect(struct soc
extern int dccp_v4_checksum(const struct sk_buff *skb,
const __be32 saddr, const __be32 daddr);
-extern int dccp_v4_send_reset(struct sock *sk,
- enum dccp_reset_codes code);
+extern int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code);
extern void dccp_send_close(struct sock *sk, const int active);
extern int dccp_invalid_packet(struct sk_buff *skb);
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 67691a0..eac5178 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -32,7 +32,7 @@ static void dccp_fin(struct sock *sk, st
static void dccp_rcv_close(struct sock *sk, struct sk_buff *skb)
{
- dccp_v4_send_reset(sk, DCCP_RESET_CODE_CLOSED);
+ dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED);
dccp_fin(sk, skb);
dccp_set_state(sk, DCCP_CLOSED);
sk_wake_async(sk, 1, POLL_HUP);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 4a2ce1c..766b619 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -457,32 +457,6 @@ void dccp_v4_send_check(struct sock *sk,
EXPORT_SYMBOL_GPL(dccp_v4_send_check);
-int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
-{
- struct sk_buff *skb;
- /*
- * FIXME: what if rebuild_header fails?
- * Should we be doing a rebuild_header here?
- */
- int err = inet_sk_rebuild_header(sk);
-
- if (err != 0)
- return err;
-
- skb = dccp_make_reset(sk, sk->sk_dst_cache, code);
- if (skb != NULL) {
- const struct inet_sock *inet = inet_sk(sk);
-
- memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
- err = ip_build_and_send_pkt(skb, sk,
- inet->saddr, inet->daddr, NULL);
- if (err = NET_XMIT_CN)
- err = 0;
- }
-
- return err;
-}
-
static inline u64 dccp_v4_init_sequence(const struct sock *sk,
const struct sk_buff *skb)
{
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 0cc2bcf..9922d26 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -323,8 +323,8 @@ struct sk_buff *dccp_make_response(struc
EXPORT_SYMBOL_GPL(dccp_make_response);
-struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
- const enum dccp_reset_codes code)
+static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
+ const enum dccp_reset_codes code)
{
struct dccp_hdr *dh;
@@ -366,14 +366,34 @@ struct sk_buff *dccp_make_reset(struct s
dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dp->dccps_gsr);
dccp_hdr_reset(skb)->dccph_reset_code = code;
-
- dh->dccph_checksum = dccp_v4_checksum(skb, inet_sk(sk)->saddr,
- inet_sk(sk)->daddr);
+ inet_csk(sk)->icsk_af_ops->send_check(sk, skb->len, skb);
DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
return skb;
}
+int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
+{
+ /*
+ * FIXME: what if rebuild_header fails?
+ * Should we be doing a rebuild_header here?
+ */
+ int err = inet_sk_rebuild_header(sk);
+
+ if (err = 0) {
+ struct sk_buff *skb = dccp_make_reset(sk, sk->sk_dst_cache,
+ code);
+ if (skb != NULL) {
+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+ err = inet_csk(sk)->icsk_af_ops->queue_xmit(skb, 0);
+ if (err = NET_XMIT_CN)
+ err = 0;
+ }
+ }
+
+ return err;
+}
+
/*
* Do all connect socket setups that can be done AF independent.
*/
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index d7c7866..5244415 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -31,7 +31,7 @@ static void dccp_write_err(struct sock *
sk->sk_err = sk->sk_err_soft ? : ETIMEDOUT;
sk->sk_error_report(sk);
- dccp_v4_send_reset(sk, DCCP_RESET_CODE_ABORTED);
+ dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
dccp_done(sk);
DCCP_INC_STATS_BH(DCCP_MIB_ABORTONTIMEOUT);
}
--
1.2.2.gd27d
^ permalink raw reply related
* [PATCH 3/7] [DCCP]: Move dccp_[un]hash from ipv4.c to the core
From: Arnaldo Carvalho de Melo @ 2006-02-23 22:12 UTC (permalink / raw)
To: dccp
As this is used by both ipv4 and ipv6 and is not ipv4 specific.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
net/dccp/dccp.h | 1 +
net/dccp/ipv4.c | 14 +-------------
net/dccp/ipv6.c | 2 +-
net/dccp/proto.c | 14 ++++++++++++++
4 files changed, 17 insertions(+), 14 deletions(-)
5f50d3a8059644b039b19a43200800783658e130
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 8f3903b..b6ea4cc 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -238,6 +238,7 @@ extern struct sk_buff *dccp_make_respons
extern int dccp_connect(struct sock *sk);
extern int dccp_disconnect(struct sock *sk, int flags);
+extern void dccp_hash(struct sock *sk);
extern void dccp_unhash(struct sock *sk);
extern int dccp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index b26a4f8..34d1b11 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -44,18 +44,6 @@ static int dccp_v4_get_port(struct sock
inet_csk_bind_conflict);
}
-static void dccp_v4_hash(struct sock *sk)
-{
- inet_hash(&dccp_hashinfo, sk);
-}
-
-void dccp_unhash(struct sock *sk)
-{
- inet_unhash(&dccp_hashinfo, sk);
-}
-
-EXPORT_SYMBOL_GPL(dccp_unhash);
-
int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
struct inet_sock *inet = inet_sk(sk);
@@ -1048,7 +1036,7 @@ struct proto dccp_prot = {
.sendmsg = dccp_sendmsg,
.recvmsg = dccp_recvmsg,
.backlog_rcv = dccp_v4_do_rcv,
- .hash = dccp_v4_hash,
+ .hash = dccp_hash,
.unhash = dccp_unhash,
.accept = inet_csk_accept,
.get_port = dccp_v4_get_port,
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 84651bc..904967b 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -53,7 +53,7 @@ static void dccp_v6_hash(struct sock *sk
{
if (sk->sk_state != DCCP_CLOSED) {
if (inet_csk(sk)->icsk_af_ops = &dccp_ipv6_mapped) {
- dccp_prot.hash(sk);
+ dccp_hash(sk);
return;
}
local_bh_disable();
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 1f5c92d..7ac935a 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -97,6 +97,20 @@ const char *dccp_state_name(const int st
EXPORT_SYMBOL_GPL(dccp_state_name);
+void dccp_hash(struct sock *sk)
+{
+ inet_hash(&dccp_hashinfo, sk);
+}
+
+EXPORT_SYMBOL_GPL(dccp_hash);
+
+void dccp_unhash(struct sock *sk)
+{
+ inet_unhash(&dccp_hashinfo, sk);
+}
+
+EXPORT_SYMBOL_GPL(dccp_unhash);
+
int dccp_init_sock(struct sock *sk)
{
struct dccp_sock *dp = dccp_sk(sk);
--
1.2.2.gd27d
^ permalink raw reply related
* [PATCH 6/7] [DCCP]: Rename init_dccp_v4_mibs to dccp_mib_init
From: Arnaldo Carvalho de Melo @ 2006-02-23 22:12 UTC (permalink / raw)
To: dccp
And introduce dccp_mib_exit grouping previously open coded sequence.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
net/dccp/proto.c | 18 +++++++++++-------
1 files changed, 11 insertions(+), 7 deletions(-)
2250710f2979bf1e47bba2f6e3fcadfd9a686071
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index a57a8b6..c048d5b 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -933,7 +933,7 @@ void dccp_ctl_sock_exit(void)
EXPORT_SYMBOL_GPL(dccp_ctl_sock_exit);
#endif
-static int __init init_dccp_v4_mibs(void)
+static int __init dccp_mib_init(void)
{
int rc = -ENOMEM;
@@ -955,6 +955,13 @@ out_free_one:
}
+static int dccp_mib_exit(void)
+{
+ free_percpu(dccp_statistics[0]);
+ free_percpu(dccp_statistics[1]);
+ dccp_statistics[0] = dccp_statistics[1] = NULL;
+}
+
static int thash_entries;
module_param(thash_entries, int, 0444);
MODULE_PARM_DESC(thash_entries, "Number of ehash buckets");
@@ -1044,7 +1051,7 @@ static int __init dccp_init(void)
INIT_HLIST_HEAD(&dccp_hashinfo.bhash[i].chain);
}
- rc = init_dccp_v4_mibs();
+ rc = dccp_mib_init();
if (rc)
goto out_free_dccp_bhash;
@@ -1075,9 +1082,7 @@ out_unregister_protosw:
inet_unregister_protosw(&dccp_v4_protosw);
inet_del_protocol(&dccp_protocol, IPPROTO_DCCP);
out_free_dccp_v4_mibs:
- free_percpu(dccp_statistics[0]);
- free_percpu(dccp_statistics[1]);
- dccp_statistics[0] = dccp_statistics[1] = NULL;
+ dccp_mib_exit();
out_free_dccp_bhash:
free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
dccp_hashinfo.bhash = NULL;
@@ -1102,8 +1107,7 @@ static void __exit dccp_fini(void)
if (inet_del_protocol(&dccp_protocol, IPPROTO_DCCP) < 0)
printk(dccp_del_proto_err_msg);
- free_percpu(dccp_statistics[0]);
- free_percpu(dccp_statistics[1]);
+ dccp_mib_exit();
free_pages((unsigned long)dccp_hashinfo.bhash,
get_order(dccp_hashinfo.bhash_size *
sizeof(struct inet_bind_hashbucket)));
--
1.2.2.gd27d
^ permalink raw reply related
* [PATCH 5/7] [DCCP]: Move dccp_hashinfo from ipv4.c to the core
From: Arnaldo Carvalho de Melo @ 2006-02-23 22:12 UTC (permalink / raw)
To: dccp
As it is used by both ipv4 and ipv6.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
net/dccp/ipv4.c | 8 --------
net/dccp/proto.c | 8 ++++++++
2 files changed, 8 insertions(+), 8 deletions(-)
dd931ecebe9c97b8a75ac0b720c0da5f5c452408
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index f087593..a7332f0 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -30,14 +30,6 @@
#include "dccp.h"
#include "feat.h"
-struct inet_hashinfo __cacheline_aligned dccp_hashinfo = {
- .lhash_lock = RW_LOCK_UNLOCKED,
- .lhash_users = ATOMIC_INIT(0),
- .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(dccp_hashinfo.lhash_wait),
-};
-
-EXPORT_SYMBOL_GPL(dccp_hashinfo);
-
static int dccp_v4_get_port(struct sock *sk, const unsigned short snum)
{
return inet_csk_get_port(&dccp_hashinfo, sk, snum,
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 7ac935a..a57a8b6 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -47,6 +47,14 @@ atomic_t dccp_orphan_count = ATOMIC_INIT
EXPORT_SYMBOL_GPL(dccp_orphan_count);
+struct inet_hashinfo __cacheline_aligned dccp_hashinfo = {
+ .lhash_lock = RW_LOCK_UNLOCKED,
+ .lhash_users = ATOMIC_INIT(0),
+ .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(dccp_hashinfo.lhash_wait),
+};
+
+EXPORT_SYMBOL_GPL(dccp_hashinfo);
+
static struct net_protocol dccp_protocol = {
.handler = dccp_v4_rcv,
.err_handler = dccp_v4_err,
--
1.2.2.gd27d
^ permalink raw reply related
* [PATCH 0/7][DCCP]: Improvements
From: Arnaldo Carvalho de Melo @ 2006-02-23 22:12 UTC (permalink / raw)
To: dccp
Hi David,
Please consider pulling from:
master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.17.git
Best Regards,
- Arnaldo
b/net/dccp/Makefile | 7 -
b/net/dccp/dccp.h | 6 -
b/net/dccp/input.c | 2
b/net/dccp/ipv4.c | 26 ----
b/net/dccp/ipv6.c | 4
b/net/dccp/options.c | 2
b/net/dccp/output.c | 30 ++++-
b/net/dccp/proto.c | 103 +++++++++++++++++++
b/net/dccp/timer.c | 3
net/dccp/dccp.h | 11 --
net/dccp/ipv4.c | 271 +++++++++++++++++++++++++++------------------------
net/dccp/ipv6.c | 2
net/dccp/output.c | 6 -
net/dccp/proto.c | 176 +++++++--------------------------
14 files changed, 327 insertions(+), 322 deletions(-)
^ permalink raw reply
* Re: [PATCH 0/4][DCCP]: Improvements
From: David S. Miller @ 2006-02-23 1:51 UTC (permalink / raw)
To: dccp
In-Reply-To: <11406443213110-git-send-email-acme@mandriva.com>
From: Arnaldo Carvalho de Melo <acme@mandriva.com>
Date: Wed, 22 Feb 2006 18:38:41 -0300
> Please consider pulling from:
>
> master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.17.git
Pulled thanks.
> P.S.: Testing git-send-email.perl from latest git repo, please let me know
> of any bogosity.
Looks good from here.
^ permalink raw reply
* [PATCH 3/4] [DCCP]: Call dccp_feat_init more early in dccp_v4_init_sock
From: Arnaldo Carvalho de Melo @ 2006-02-22 21:38 UTC (permalink / raw)
To: dccp
So that dccp_feat_clean doesn't get confused with uninitialized list_heads.
Noticed when testing with no ccid kernel modules.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
net/dccp/ipv4.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
f79878f104ec370040510ae7db907b4504c46d3a
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 54fabb1..4a2ce1c 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1051,7 +1051,10 @@ int dccp_v4_init_sock(struct sock *sk)
* setsockopt(CCIDs-I-want/accept). -acme
*/
if (likely(!dccp_ctl_socket_init)) {
- int rc;
+ int rc = dccp_feat_init(sk);
+
+ if (rc)
+ return rc;
if (dp->dccps_options.dccpo_send_ack_vector) {
dp->dccps_hc_rx_ackvec = dccp_ackvec_alloc(GFP_KERNEL);
@@ -1075,10 +1078,6 @@ int dccp_v4_init_sock(struct sock *sk)
dp->dccps_hc_rx_ccid = dp->dccps_hc_tx_ccid = NULL;
return -ENOMEM;
}
-
- rc = dccp_feat_init(sk);
- if (rc)
- return rc;
} else {
/* control socket doesn't need feat nego */
INIT_LIST_HEAD(&dp->dccps_options.dccpo_pending);
--
1.1.GIT
^ permalink raw reply related
* [PATCH 1/4] [DCCP]: Make CCID2 be the default
From: Arnaldo Carvalho de Melo @ 2006-02-22 21:38 UTC (permalink / raw)
To: dccp
As per the draft. This fixes the build when netfilter dccp components are built
and dccp isn't. Thanks to Reuben Farrelly for reporting this.
The following changesets will introduce /proc/sys/net/dccp/defaults/ to give
more flexibility to DCCP developers and testers while apps doesn't use
setsockopt to specify the desired CCID, etc.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
include/linux/dccp.h | 9 ---------
1 files changed, 0 insertions(+), 9 deletions(-)
499dbc5e7f577a3a1712cee8dcb0e540082ab81d
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 496dbad..e35f680 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -320,17 +320,8 @@ static inline unsigned int dccp_hdr_len(
/* initial values for each feature */
#define DCCPF_INITIAL_SEQUENCE_WINDOW 100
#define DCCPF_INITIAL_ACK_RATIO 2
-
-#if defined(CONFIG_IP_DCCP_CCID2) || defined(CONFIG_IP_DCCP_CCID2_MODULE)
#define DCCPF_INITIAL_CCID 2
#define DCCPF_INITIAL_SEND_ACK_VECTOR 1
-#elif defined(CONFIG_IP_DCCP_CCID3) || defined(CONFIG_IP_DCCP_CCID3_MODULE)
-#define DCCPF_INITIAL_CCID 3
-#define DCCPF_INITIAL_SEND_ACK_VECTOR 0
-#else
-#error "At least one CCID must be built as the default"
-#endif
-
/* FIXME: for now we're default to 1 but it should really be 0 */
#define DCCPF_INITIAL_SEND_NDP_COUNT 1
--
1.1.GIT
^ permalink raw reply related
* [PATCH 4/4] [DCCP] feat: Introduce sysctls for the default features
From: Arnaldo Carvalho de Melo @ 2006-02-22 21:38 UTC (permalink / raw)
To: dccp
[root@qemu ~]# for a in /proc/sys/net/dccp/default/* ; do echo $a ; cat $a ; done
/proc/sys/net/dccp/default/ack_ratio
2
/proc/sys/net/dccp/default/rx_ccid
3
/proc/sys/net/dccp/default/send_ackvec
1
/proc/sys/net/dccp/default/send_ndp
1
/proc/sys/net/dccp/default/seq_window
100
/proc/sys/net/dccp/default/tx_ccid
3
[root@qemu ~]#
So if wanting to test ccid3 as the tx CCID one can just do:
[root@qemu ~]# echo 3 > /proc/sys/net/dccp/default/tx_ccid
[root@qemu ~]# echo 2 > /proc/sys/net/dccp/default/rx_ccid
[root@qemu ~]# cat /proc/sys/net/dccp/default/[tr]x_ccid
2
3
[root@qemu ~]#
Of course we also need the setsockopt for each app to tell its preferences, but
for testing or defining something other than CCID2 as the default for apps that
don't explicitely set their preference the sysctl interface is handy.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
include/linux/sysctl.h | 16 ++++++
net/dccp/Makefile | 2 +
net/dccp/dccp.h | 14 +++++
net/dccp/options.c | 22 +++++----
net/dccp/proto.c | 9 +++
net/dccp/sysctl.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 176 insertions(+), 11 deletions(-)
create mode 100644 net/dccp/sysctl.c
df0bb8f0450110107ef4c4dc641b3e626e750565
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 42ebee8..195e936 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -209,6 +209,7 @@ enum
NET_SCTP\x17,
NET_LLC\x18,
NET_NETFILTER\x19,
+ NET_DCCP ,
};
/* /proc/sys/kernel/random */
@@ -569,6 +570,21 @@ enum {
__NET_NEIGH_MAX
};
+/* /proc/sys/net/dccp */
+enum {
+ NET_DCCP_DEFAULT=1,
+};
+
+/* /proc/sys/net/dccp/default */
+enum {
+ NET_DCCP_DEFAULT_SEQ_WINDOW = 1,
+ NET_DCCP_DEFAULT_RX_CCID = 2,
+ NET_DCCP_DEFAULT_TX_CCID = 3,
+ NET_DCCP_DEFAULT_ACK_RATIO = 4,
+ NET_DCCP_DEFAULT_SEND_ACKVEC = 5,
+ NET_DCCP_DEFAULT_SEND_NDP = 6,
+};
+
/* /proc/sys/net/ipx */
enum {
NET_IPX_PPROP_BROADCASTING=1,
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index 5736ace..7af0569 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -11,6 +11,8 @@ dccp-$(CONFIG_IP_DCCP_ACKVEC) += ackvec.
obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o
+dccp-$(CONFIG_SYSCTL) += sysctl.o
+
dccp_diag-y := diag.o
obj-y += ccids/
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 1764adb..f059541 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -433,4 +433,18 @@ static inline void timeval_sub_usecs(str
}
}
+#ifdef CONFIG_SYSCTL
+extern int dccp_sysctl_init(void);
+extern void dccp_sysctl_exit(void);
+#else
+static inline int dccp_sysctl_init(void)
+{
+ return 0;
+}
+
+static inline void dccp_sysctl_exit(void)
+{
+}
+#endif
+
#endif /* _DCCP_H */
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 7d73b33..3ecd319 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -23,19 +23,21 @@
#include "dccp.h"
#include "feat.h"
-/* stores the default values for new connection. may be changed with sysctl */
-static const struct dccp_options dccpo_default_values = {
- .dccpo_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW,
- .dccpo_rx_ccid = DCCPF_INITIAL_CCID,
- .dccpo_tx_ccid = DCCPF_INITIAL_CCID,
- .dccpo_ack_ratio = DCCPF_INITIAL_ACK_RATIO,
- .dccpo_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR,
- .dccpo_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT,
-};
+int dccp_feat_default_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW;
+int dccp_feat_default_rx_ccid = DCCPF_INITIAL_CCID;
+int dccp_feat_default_tx_ccid = DCCPF_INITIAL_CCID;
+int dccp_feat_default_ack_ratio = DCCPF_INITIAL_ACK_RATIO;
+int dccp_feat_default_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR;
+int dccp_feat_default_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT;
void dccp_options_init(struct dccp_options *dccpo)
{
- memcpy(dccpo, &dccpo_default_values, sizeof(*dccpo));
+ dccpo->dccpo_sequence_window = dccp_feat_default_sequence_window;
+ dccpo->dccpo_rx_ccid = dccp_feat_default_rx_ccid;
+ dccpo->dccpo_tx_ccid = dccp_feat_default_tx_ccid;
+ dccpo->dccpo_ack_ratio = dccp_feat_default_ack_ratio;
+ dccpo->dccpo_send_ack_vector = dccp_feat_default_send_ack_vector;
+ dccpo->dccpo_send_ndp_count = dccp_feat_default_send_ndp_count;
}
static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len)
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 1e9fdf6..04315c3 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -934,11 +934,17 @@ static int __init dccp_init(void)
if (rc)
goto out_unregister_protosw;
- rc = dccp_ctl_sock_init();
+ rc = dccp_sysctl_init();
if (rc)
goto out_ackvec_exit;
+
+ rc = dccp_ctl_sock_init();
+ if (rc)
+ goto out_sysctl_exit;
out:
return rc;
+out_sysctl_exit:
+ dccp_sysctl_exit();
out_ackvec_exit:
dccp_ackvec_exit();
out_unregister_protosw:
@@ -983,6 +989,7 @@ static void __exit dccp_fini(void)
kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
proto_unregister(&dccp_prot);
dccp_ackvec_exit();
+ dccp_sysctl_exit();
}
module_init(dccp_init);
diff --git a/net/dccp/sysctl.c b/net/dccp/sysctl.c
new file mode 100644
index 0000000..64c89e9
--- /dev/null
+++ b/net/dccp/sysctl.c
@@ -0,0 +1,124 @@
+/*
+ * net/dccp/sysctl.c
+ *
+ * An implementation of the DCCP protocol
+ * Arnaldo Carvalho de Melo <acme@mandriva.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License v2
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/sysctl.h>
+
+#ifndef CONFIG_SYSCTL
+#error This file should not be compiled without CONFIG_SYSCTL defined
+#endif
+
+extern int dccp_feat_default_sequence_window;
+extern int dccp_feat_default_rx_ccid;
+extern int dccp_feat_default_tx_ccid;
+extern int dccp_feat_default_ack_ratio;
+extern int dccp_feat_default_send_ack_vector;
+extern int dccp_feat_default_send_ndp_count;
+
+static struct ctl_table dccp_default_table[] = {
+ {
+ .ctl_name = NET_DCCP_DEFAULT_SEQ_WINDOW,
+ .procname = "seq_window",
+ .data = &dccp_feat_default_sequence_window,
+ .maxlen = sizeof(dccp_feat_default_sequence_window),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .ctl_name = NET_DCCP_DEFAULT_RX_CCID,
+ .procname = "rx_ccid",
+ .data = &dccp_feat_default_rx_ccid,
+ .maxlen = sizeof(dccp_feat_default_rx_ccid),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .ctl_name = NET_DCCP_DEFAULT_TX_CCID,
+ .procname = "tx_ccid",
+ .data = &dccp_feat_default_tx_ccid,
+ .maxlen = sizeof(dccp_feat_default_tx_ccid),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .ctl_name = NET_DCCP_DEFAULT_ACK_RATIO,
+ .procname = "ack_ratio",
+ .data = &dccp_feat_default_ack_ratio,
+ .maxlen = sizeof(dccp_feat_default_ack_ratio),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .ctl_name = NET_DCCP_DEFAULT_SEND_ACKVEC,
+ .procname = "send_ackvec",
+ .data = &dccp_feat_default_send_ack_vector,
+ .maxlen = sizeof(dccp_feat_default_send_ack_vector),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ {
+ .ctl_name = NET_DCCP_DEFAULT_SEND_NDP,
+ .procname = "send_ndp",
+ .data = &dccp_feat_default_send_ndp_count,
+ .maxlen = sizeof(dccp_feat_default_send_ndp_count),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ { .ctl_name = 0, }
+};
+
+static struct ctl_table dccp_table[] = {
+ {
+ .ctl_name = NET_DCCP_DEFAULT,
+ .procname = "default",
+ .mode = 0555,
+ .child = dccp_default_table,
+ },
+ { .ctl_name = 0, },
+};
+
+static struct ctl_table dccp_dir_table[] = {
+ {
+ .ctl_name = NET_DCCP,
+ .procname = "dccp",
+ .mode = 0555,
+ .child = dccp_table,
+ },
+ { .ctl_name = 0, },
+};
+
+static struct ctl_table dccp_root_table[] = {
+ {
+ .ctl_name = CTL_NET,
+ .procname = "net",
+ .mode = 0555,
+ .child = dccp_dir_table,
+ },
+ { .ctl_name = 0, },
+};
+
+static struct ctl_table_header *dccp_table_header;
+
+int __init dccp_sysctl_init(void)
+{
+ dccp_table_header = register_sysctl_table(dccp_root_table, 1);
+
+ return dccp_table_header != NULL ? 0 : -ENOMEM;
+}
+
+void dccp_sysctl_exit(void)
+{
+ if (dccp_table_header != NULL) {
+ unregister_sysctl_table(dccp_table_header);
+ dccp_table_header = NULL;
+ }
+}
--
1.1.GIT
^ permalink raw reply related
* [PATCH 2/4] [DCCP]: Kconfig tidy up
From: Arnaldo Carvalho de Melo @ 2006-02-22 21:38 UTC (permalink / raw)
To: dccp
Make CCID2 and CCID3 default to what was selected for DCCP and use the standard
short description for the CCIDs (TCP-Like & TCP-Friendly).
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
---
net/dccp/ccids/Kconfig | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
a28388caffd72cfbc92d2504344f24af59b7ed77
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 422af19..ca00191 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -2,8 +2,9 @@ menu "DCCP CCIDs Configuration (EXPERIME
depends on IP_DCCP && EXPERIMENTAL
config IP_DCCP_CCID2
- tristate "CCID2 (TCP) (EXPERIMENTAL)"
+ tristate "CCID2 (TCP-Like) (EXPERIMENTAL)"
depends on IP_DCCP
+ def_tristate IP_DCCP
select IP_DCCP_ACKVEC
---help---
CCID 2, TCP-like Congestion Control, denotes Additive Increase,
@@ -30,8 +31,9 @@ config IP_DCCP_CCID2
If in doubt, say M.
config IP_DCCP_CCID3
- tristate "CCID3 (TFRC) (EXPERIMENTAL)"
+ tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
depends on IP_DCCP
+ def_tristate IP_DCCP
---help---
CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
rate-controlled congestion control mechanism. TFRC is designed to
--
1.1.GIT
^ permalink raw reply related
* [PATCH 0/4][DCCP]: Improvements
From: Arnaldo Carvalho de Melo @ 2006-02-22 21:38 UTC (permalink / raw)
To: dccp
Hi David,
Please consider pulling from:
master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.17.git
Best Regards,
P.S.: Testing git-send-email.perl from latest git repo, please let me know
of any bogosity.
- Arnaldo
include/linux/dccp.h | 10 ---
include/linux/sysctl.h | 16 ++++++
net/dccp/Makefile | 2
net/dccp/ccids/Kconfig | 7 +-
net/dccp/dccp.h | 14 +++++
net/dccp/ipv4.c | 10 +--
net/dccp/options.c | 22 ++++----
net/dccp/proto.c | 9 +++
net/dccp/sysctl.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++-
9 files changed, 184 insertions(+), 31 deletions(-)
^ permalink raw reply
* Re: [PATCH] Mandatory Option Draft Cleanup
From: Hagen Paul Pfeifer @ 2006-02-22 11:38 UTC (permalink / raw)
To: dccp
Sorry for the non-informative subject line! ;-)
HGN
--
Living on Earth may be expensive, but it includes
an annual free trip around the Sun.
^ permalink raw reply
* [PATCH]
From: Hagen Paul Pfeifer @ 2006-02-22 11:33 UTC (permalink / raw)
To: dccp
[-- Attachment #1: Type: text/plain, Size: 531 bytes --]
According to dccp draft (draft-ietf-dccp-spec-13.txt) section 5.8.2 (Mandatory
Option) the following patch correct the handling of the following cases:
1) "... and any Mandatory options received on DCCP-Data packets MUST be
ignored."
2) "The connection is in error and should be reset with Reset Code 5, ...
if option O is absent (Mandatory was the last byte of the option list), or
if option O equals Mandatory."
options.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
Best regards
Hagen Pfeifer
[-- Attachment #2: mandatory.patch --]
[-- Type: text/plain, Size: 635 bytes --]
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 7d73b33..3db9aad 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -107,7 +107,8 @@ int dccp_parse_options(struct sock *sk,
case DCCPO_MANDATORY:
if (mandatory)
goto out_invalid_option;
- mandatory = 1;
+ if (pkt_type != DCCP_PKT_DATA)
+ mandatory = 1;
break;
case DCCPO_NDP_COUNT:
if (len > 3)
@@ -247,6 +248,10 @@ int dccp_parse_options(struct sock *sk,
mandatory = 0;
}
+ /* mandatory was the last byte in option list -> reset connection */
+ if (mandatory)
+ goto out_invalid_option;
+
return 0;
out_invalid_option:
^ permalink raw reply related
* Re: [PATCH 1/1][DCCP]: sparse endianness annotations
From: Arnaldo Carvalho de Melo @ 2006-02-22 1:27 UTC (permalink / raw)
To: dccp
In-Reply-To: <39e6f6c70602211630m52d57c43m5365835ebad48e0@mail.gmail.com>
On 2/21/06, David S. Miller <davem@davemloft.net> wrote:
> From: "Arnaldo Carvalho de Melo" <acme@ghostprotocols.net>
> Date: Tue, 21 Feb 2006 21:49:14 -0300
>
> > Do you prefer? Today I talked with our git guy (Eduardo Habkost) and
> > changed my mind, doing things (duh!) in "master" and using git-fetch/
> > git-rebase to track your net-2.6.17 tree seems less noisy on Linus
> > git log history :-)
>
> I think I'm more likely to make mistakes if you use branches
> _unless_ you list the branch in the URL like this:
>
> --------------------
> Please pull from:
>
> $(GIT_URL) $(BRANCH_NAME)
> --------------------
>
> because I just copy&paste the line into a "git pull" command.
Okie Dokie, sensible, will use if I have a need for some longer lived
public (master.kernel.org/git) branch.
- Arnaldo
^ permalink raw reply
* Re: [PATCH 1/1][DCCP]: sparse endianness annotations
From: David S. Miller @ 2006-02-22 0:58 UTC (permalink / raw)
To: dccp
In-Reply-To: <39e6f6c70602211630m52d57c43m5365835ebad48e0@mail.gmail.com>
From: "Arnaldo Carvalho de Melo" <acme@ghostprotocols.net>
Date: Tue, 21 Feb 2006 21:49:14 -0300
> Do you prefer? Today I talked with our git guy (Eduardo Habkost) and
> changed my mind, doing things (duh!) in "master" and using git-fetch/
> git-rebase to track your net-2.6.17 tree seems less noisy on Linus
> git log history :-)
I think I'm more likely to make mistakes if you use branches
_unless_ you list the branch in the URL like this:
--------------------
Please pull from:
$(GIT_URL) $(BRANCH_NAME)
--------------------
because I just copy&paste the line into a "git pull" command.
^ permalink raw reply
* Re: [PATCH 1/1][DCCP]: sparse endianness annotations
From: Arnaldo Carvalho de Melo @ 2006-02-22 0:49 UTC (permalink / raw)
To: dccp
In-Reply-To: <39e6f6c70602211630m52d57c43m5365835ebad48e0@mail.gmail.com>
On 2/21/06, David S. Miller <davem@davemloft.net> wrote:
> From: "Arnaldo Carvalho de Melo" <acme@ghostprotocols.net>
> Date: Tue, 21 Feb 2006 21:30:15 -0300
>
> > Please consider pulling from:
> >
> > master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.17.git
>
> Pulled, thanks a lot.
>
> So are you using branches or not? :-)))
Do you prefer? Today I talked with our git guy (Eduardo Habkost) and
changed my mind, doing things (duh!) in "master" and using git-fetch/
git-rebase to track your net-2.6.17 tree seems less noisy on Linus
git log history :-)
- Arnaldo
^ permalink raw reply
* Re: [PATCH 1/1][DCCP]: sparse endianness annotations
From: David S. Miller @ 2006-02-22 0:41 UTC (permalink / raw)
To: dccp
In-Reply-To: <39e6f6c70602211630m52d57c43m5365835ebad48e0@mail.gmail.com>
From: "Arnaldo Carvalho de Melo" <acme@ghostprotocols.net>
Date: Tue, 21 Feb 2006 21:30:15 -0300
> Please consider pulling from:
>
> master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.17.git
Pulled, thanks a lot.
So are you using branches or not? :-)))
^ permalink raw reply
* [PATCH 1/1][DCCP]: sparse endianness annotations
From: Arnaldo Carvalho de Melo @ 2006-02-22 0:30 UTC (permalink / raw)
To: dccp
[-- Attachment #1: Type: text/plain, Size: 144 bytes --]
Hi David,
Please consider pulling from:
master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.17.git
Best Regards,
- Arnaldo
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 1.patch --]
[-- Type: text/x-patch; name="1.patch", Size: 14552 bytes --]
tree b4bd21110589affc70a7f1eba2681c99355b9f83
parent edbccfd94bf46e3d3204c43f7a36284c88427f22
author Al Viro <viro@zeniv.linux.org.uk> 1140463198 -0300
committer Arnaldo Carvalho de Melo <acme@mandriva.com> 1140540398 -0300
[DCCP]: sparse endianness annotations
This also fixes the layout of dccp_hdr short sequence numbers, problem was not
fatal now as we only support long (48 bits) sequence numbers.
Signed-off-by: Andrea Bittau <a.bittau@cs.ucl.ac.uk>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
------------------------------------------------------------------------------
include/linux/dccp.h | 52 +++++++++++++++++++------------------------------
net/dccp/ccids/ccid3.c | 6 ++---
net/dccp/dccp.h | 23 +++++----------------
net/dccp/ipv4.c | 12 +++++------
net/dccp/ipv6.c | 4 +--
net/dccp/options.c | 27 ++++++++++++-------------
net/dccp/proto.c | 6 ++---
7 files changed, 54 insertions(+), 76 deletions(-)
------------------------------------------------------------------------------
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index bdd756c..496dbad 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -18,7 +18,7 @@
* @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x
*/
struct dccp_hdr {
- __u16 dccph_sport,
+ __be16 dccph_sport,
dccph_dport;
__u8 dccph_doff;
#if defined(__LITTLE_ENDIAN_BITFIELD)
@@ -32,18 +32,18 @@ struct dccp_hdr {
#endif
__u16 dccph_checksum;
#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u32 dccph_x:1,
+ __u8 dccph_x:1,
dccph_type:4,
- dccph_reserved:3,
- dccph_seq:24;
+ dccph_reserved:3;
#elif defined(__BIG_ENDIAN_BITFIELD)
- __u32 dccph_reserved:3,
+ __u8 dccph_reserved:3,
dccph_type:4,
- dccph_x:1,
- dccph_seq:24;
+ dccph_x:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
+ __u8 dccph_seq2;
+ __be16 dccph_seq;
};
/**
@@ -52,7 +52,7 @@ struct dccp_hdr {
* @dccph_seq_low - low 24 bits of a 48 bit seq packet
*/
struct dccp_hdr_ext {
- __u32 dccph_seq_low;
+ __be32 dccph_seq_low;
};
/**
@@ -62,7 +62,7 @@ struct dccp_hdr_ext {
* @dccph_req_options - list of options (must be a multiple of 32 bits
*/
struct dccp_hdr_request {
- __u32 dccph_req_service;
+ __be32 dccph_req_service;
};
/**
* struct dccp_hdr_ack_bits - acknowledgment bits common to most packets
@@ -71,9 +71,9 @@ struct dccp_hdr_request {
* @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
*/
struct dccp_hdr_ack_bits {
- __u32 dccph_reserved1:8,
- dccph_ack_nr_high:24;
- __u32 dccph_ack_nr_low;
+ __be16 dccph_reserved1;
+ __be16 dccph_ack_nr_high;
+ __be32 dccph_ack_nr_low;
};
/**
* struct dccp_hdr_response - Conection initiation response header
@@ -85,7 +85,7 @@ struct dccp_hdr_ack_bits {
*/
struct dccp_hdr_response {
struct dccp_hdr_ack_bits dccph_resp_ack;
- __u32 dccph_resp_service;
+ __be32 dccph_resp_service;
};
/**
@@ -269,16 +269,12 @@ static inline unsigned int dccp_basic_hd
static inline __u64 dccp_hdr_seq(const struct sk_buff *skb)
{
const struct dccp_hdr *dh = dccp_hdr(skb);
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u64 seq_nr = ntohl(dh->dccph_seq << 8);
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u64 seq_nr = ntohl(dh->dccph_seq);
-#else
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
+ __u64 seq_nr = ntohs(dh->dccph_seq);
if (dh->dccph_x != 0)
seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low);
+ else
+ seq_nr += (u32)dh->dccph_seq2 << 16;
return seq_nr;
}
@@ -296,13 +292,7 @@ static inline struct dccp_hdr_ack_bits *
static inline u64 dccp_hdr_ack_seq(const struct sk_buff *skb)
{
const struct dccp_hdr_ack_bits *dhack = dccp_hdr_ack_bits(skb);
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- return (((u64)ntohl(dhack->dccph_ack_nr_high << 8)) << 32) + ntohl(dhack->dccph_ack_nr_low);
-#elif defined(__BIG_ENDIAN_BITFIELD)
- return (((u64)ntohl(dhack->dccph_ack_nr_high)) << 32) + ntohl(dhack->dccph_ack_nr_low);
-#else
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
+ return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) + ntohl(dhack->dccph_ack_nr_low);
}
static inline struct dccp_hdr_response *dccp_hdr_response(struct sk_buff *skb)
@@ -387,7 +377,7 @@ struct dccp_request_sock {
struct inet_request_sock dreq_inet_rsk;
__u64 dreq_iss;
__u64 dreq_isr;
- __u32 dreq_service;
+ __be32 dreq_service;
};
static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
@@ -415,13 +405,13 @@ enum dccp_role {
struct dccp_service_list {
__u32 dccpsl_nr;
- __u32 dccpsl_list[0];
+ __be32 dccpsl_list[0];
};
#define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1)
static inline int dccp_list_has_service(const struct dccp_service_list *sl,
- const u32 service)
+ const __be32 service)
{
if (likely(sl != NULL)) {
u32 i = sl->dccpsl_nr;
@@ -467,7 +457,7 @@ struct dccp_sock {
__u64 dccps_gss;
__u64 dccps_gsr;
__u64 dccps_gar;
- __u32 dccps_service;
+ __be32 dccps_service;
struct dccp_service_list *dccps_service_list;
struct timeval dccps_timestamp_time;
__u32 dccps_timestamp_echo;
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index a357c15..c0d2ef7 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -615,7 +615,7 @@ static int ccid3_hc_tx_parse_options(str
__FUNCTION__, dccp_role(sk), sk);
rc = -EINVAL;
} else {
- opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value);
+ opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value);
ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n",
dccp_role(sk), sk,
opt_recv->ccid3or_loss_event_rate);
@@ -636,7 +636,7 @@ static int ccid3_hc_tx_parse_options(str
__FUNCTION__, dccp_role(sk), sk);
rc = -EINVAL;
} else {
- opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value);
+ opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value);
ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
dccp_role(sk), sk,
opt_recv->ccid3or_receive_rate);
@@ -777,7 +777,7 @@ static void ccid3_hc_rx_send_feedback(st
static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
{
const struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
- u32 x_recv, pinv;
+ __be32 x_recv, pinv;
BUG_ON(hcrx == NULL);
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 93f26dd..1764adb 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -262,7 +262,7 @@ extern int dccp_v4_connect(struct soc
int addr_len);
extern int dccp_v4_checksum(const struct sk_buff *skb,
- const u32 saddr, const u32 daddr);
+ const __be32 saddr, const __be32 daddr);
extern int dccp_v4_send_reset(struct sock *sk,
enum dccp_reset_codes code);
@@ -270,7 +270,7 @@ extern void dccp_send_close(struct so
extern int dccp_invalid_packet(struct sk_buff *skb);
static inline int dccp_bad_service_code(const struct sock *sk,
- const __u32 service)
+ const __be32 service)
{
const struct dccp_sock *dp = dccp_sk(sk);
@@ -334,27 +334,16 @@ static inline void dccp_hdr_set_seq(stru
{
struct dccp_hdr_ext *dhx = (struct dccp_hdr_ext *)((void *)dh +
sizeof(*dh));
-
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- dh->dccph_seq = htonl((gss >> 32)) >> 8;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- dh->dccph_seq = htonl((gss >> 32));
-#else
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
+ dh->dccph_seq2 = 0;
+ dh->dccph_seq = htons((gss >> 32) & 0xfffff);
dhx->dccph_seq_low = htonl(gss & 0xffffffff);
}
static inline void dccp_hdr_set_ack(struct dccp_hdr_ack_bits *dhack,
const u64 gsr)
{
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- dhack->dccph_ack_nr_high = htonl((gsr >> 32)) >> 8;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- dhack->dccph_ack_nr_high = htonl((gsr >> 32));
-#else
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
+ dhack->dccph_reserved1 = 0;
+ dhack->dccph_ack_nr_high = htons(gsr >> 32);
dhack->dccph_ack_nr_low = htonl(gsr & 0xffffffff);
}
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 266b6b2..54fabb1 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -498,9 +498,9 @@ int dccp_v4_conn_request(struct sock *sk
struct dccp_sock dp;
struct request_sock *req;
struct dccp_request_sock *dreq;
- const __u32 saddr = skb->nh.iph->saddr;
- const __u32 daddr = skb->nh.iph->daddr;
- const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
+ const __be32 saddr = skb->nh.iph->saddr;
+ const __be32 daddr = skb->nh.iph->daddr;
+ const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
__u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
@@ -662,8 +662,8 @@ static struct sock *dccp_v4_hnd_req(stru
return sk;
}
-int dccp_v4_checksum(const struct sk_buff *skb, const u32 saddr,
- const u32 daddr)
+int dccp_v4_checksum(const struct sk_buff *skb, const __be32 saddr,
+ const __be32 daddr)
{
const struct dccp_hdr* dh = dccp_hdr(skb);
int checksum_len;
@@ -683,7 +683,7 @@ int dccp_v4_checksum(const struct sk_buf
}
static int dccp_v4_verify_checksum(struct sk_buff *skb,
- const u32 saddr, const u32 daddr)
+ const __be32 saddr, const __be32 daddr)
{
struct dccp_hdr *dh = dccp_hdr(skb);
int checksum_len;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 80c4d04..ad5a1c6 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -264,7 +264,7 @@ failure:
}
static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
- int type, int code, int offset, __u32 info)
+ int type, int code, int offset, __be32 info)
{
struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
@@ -678,7 +678,7 @@ static int dccp_v6_conn_request(struct s
struct dccp_request_sock *dreq;
struct inet6_request_sock *ireq6;
struct ipv6_pinfo *np = inet6_sk(sk);
- const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
+ const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
__u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 7f99306..7d73b33 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -155,7 +155,7 @@ int dccp_parse_options(struct sock *sk,
if (len != 4)
goto out_invalid_option;
- opt_recv->dccpor_timestamp = ntohl(*(u32 *)value);
+ opt_recv->dccpor_timestamp = ntohl(*(__be32 *)value);
dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
dccp_timestamp(sk, &dp->dccps_timestamp_time);
@@ -169,7 +169,7 @@ int dccp_parse_options(struct sock *sk,
if (len != 4 && len != 6 && len != 8)
goto out_invalid_option;
- opt_recv->dccpor_timestamp_echo = ntohl(*(u32 *)value);
+ opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value);
dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, ackno=%llu, ",
debug_prefix,
@@ -183,9 +183,9 @@ int dccp_parse_options(struct sock *sk,
break;
if (len == 6)
- elapsed_time = ntohs(*(u16 *)(value + 4));
+ elapsed_time = ntohs(*(__be16 *)(value + 4));
else
- elapsed_time = ntohl(*(u32 *)(value + 4));
+ elapsed_time = ntohl(*(__be32 *)(value + 4));
/* Give precedence to the biggest ELAPSED_TIME */
if (elapsed_time > opt_recv->dccpor_elapsed_time)
@@ -199,9 +199,9 @@ int dccp_parse_options(struct sock *sk,
continue;
if (len == 2)
- elapsed_time = ntohs(*(u16 *)value);
+ elapsed_time = ntohs(*(__be16 *)value);
else
- elapsed_time = ntohl(*(u32 *)value);
+ elapsed_time = ntohl(*(__be32 *)value);
if (elapsed_time > opt_recv->dccpor_elapsed_time)
opt_recv->dccpor_elapsed_time = elapsed_time;
@@ -358,10 +358,10 @@ void dccp_insert_option_elapsed_time(str
*to++ = len;
if (elapsed_time_len == 2) {
- const u16 var16 = htons((u16)elapsed_time);
+ const __be16 var16 = htons((u16)elapsed_time);
memcpy(to, &var16, 2);
} else {
- const u32 var32 = htonl(elapsed_time);
+ const __be32 var32 = htonl(elapsed_time);
memcpy(to, &var32, 4);
}
@@ -392,14 +392,13 @@ EXPORT_SYMBOL_GPL(dccp_timestamp);
void dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
{
struct timeval tv;
- u32 now;
+ __be32 now;
dccp_timestamp(sk, &tv);
- now = timeval_usecs(&tv) / 10;
+ now = htonl(timeval_usecs(&tv) / 10);
/* yes this will overflow but that is the point as we want a
* 10 usec 32 bit timer which mean it wraps every 11.9 hours */
- now = htonl(now);
dccp_insert_option(sk, skb, DCCPO_TIMESTAMP, &now, sizeof(now));
}
@@ -414,7 +413,7 @@ static void dccp_insert_option_timestamp
"CLIENT TX opt: " : "server TX opt: ";
#endif
struct timeval now;
- u32 tstamp_echo;
+ __be32 tstamp_echo;
u32 elapsed_time;
int len, elapsed_time_len;
unsigned char *to;
@@ -441,10 +440,10 @@ static void dccp_insert_option_timestamp
to += 4;
if (elapsed_time_len == 2) {
- const u16 var16 = htons((u16)elapsed_time);
+ const __be16 var16 = htons((u16)elapsed_time);
memcpy(to, &var16, 2);
} else if (elapsed_time_len == 4) {
- const u32 var32 = htonl(elapsed_time);
+ const __be32 var32 = htonl(elapsed_time);
memcpy(to, &var32, 4);
}
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index ae2ab50..1e9fdf6 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -221,7 +221,7 @@ int dccp_ioctl(struct sock *sk, int cmd,
EXPORT_SYMBOL_GPL(dccp_ioctl);
-static int dccp_setsockopt_service(struct sock *sk, const u32 service,
+static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
char __user *optval, int optlen)
{
struct dccp_sock *dp = dccp_sk(sk);
@@ -349,7 +349,7 @@ int dccp_setsockopt(struct sock *sk, int
EXPORT_SYMBOL_GPL(dccp_setsockopt);
static int dccp_getsockopt_service(struct sock *sk, int len,
- u32 __user *optval,
+ __be32 __user *optval,
int __user *optlen)
{
const struct dccp_sock *dp = dccp_sk(sk);
@@ -404,7 +404,7 @@ int dccp_getsockopt(struct sock *sk, int
break;
case DCCP_SOCKOPT_SERVICE:
return dccp_getsockopt_service(sk, len,
- (u32 __user *)optval, optlen);
+ (__be32 __user *)optval, optlen);
case 128 ... 191:
return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
len, (u32 __user *)optval, optlen);
^ permalink raw reply related
* Re: [PATCH] 1/1 dccp: transmit buffering
From: Arnaldo Carvalho de Melo @ 2006-02-21 12:09 UTC (permalink / raw)
To: dccp
In-Reply-To: <cbec11ac0602061504y3507004dnf8b13d089d9fceba@mail.gmail.com>
On 2/20/06, Ian McDonald <imcdnzl@gmail.com> wrote:
> Arnaldo, (or anybody else)
>
> I can get it working with the extra lock but not without... Comments
> inline and at the end. Help much appreciated!
>
>
> > Please leave the "extern"
> >
> Yep!
>
> > I guess we don't need this lock, but instead use bh_lock_sock, check if
> > there are users, look at ccid3_hc_tx_no_feedback_timer & ccid2_hc_tx_rto_expire
> > (I left a comment even having fixed the problem, duh will fix).
>
> I'm not sure what you mean by users here. Users of what? Can you explain
Look at lock_sock(), release_sock(), bh_lock_sock(), bh_release_sock() and
at sk_receive_skb and you'll see what I mean :-)
> > sk_reset_timer() please, so that we make sure we have a reference count
> > for the sock as its going to be on a timer
> >
> Will tidyup once get other problems sorted...
>
> > No need for the {}, just one statement
>
> Understand. Lazy when removing debugging...
>
> > sk_eat_skb() later?
> >
> It would be sk_eat_skb in dccp_write_xmit for two reasons:
> 1) sk_eat_skb alters receive queue. This is write
> 2) Existing xmit doesn't seem to do anything like this. To me it looks
> like the lower level does the kfree_skb...
Scrap that suggestion, brainfart :-\
> >
> > > + dp->dccps_xmit_lock = SPIN_LOCK_UNLOCKED;
> >
> > Not needed
>
> Understand - will remove
>
> Now I have attached two patches. acme1.diff is slightly tidied up
> version of original patch and works with normal testing and netem
> testing.
>
> acme2.diff is an attempt to get rid of spinlock and use sock_lock as I
> didn't think I needed bh_sock_lock as not receiving packets as that is
> seemed aimed at that (stopping the interrupt driver trashing receive
> queues...)
I'll try to take a look later today, now have to visit a customer...
- Arnaldo
^ permalink raw reply
* Re: [PATCH 2/2][DCCP] feat: Actually change the CCID upon
From: David S. Miller @ 2006-02-21 7:54 UTC (permalink / raw)
To: dccp
In-Reply-To: <39e6f6c70602200443rcf4f551o3a7af75d848d2a80@mail.gmail.com>
From: "Arnaldo Carvalho de Melo" <acme@ghostprotocols.net>
Date: Mon, 20 Feb 2006 09:43:01 -0300
> Please consider pulling from the "dccp_upstream" branch of:
>
> master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.17.git
>
> Now there are two outstanding csets in this tree.
Pulled, thanks Arnaldo.
^ permalink raw reply
* Re: [PATCH] 1/1 dccp: transmit buffering
From: Ian McDonald @ 2006-02-21 2:14 UTC (permalink / raw)
To: dccp
In-Reply-To: <cbec11ac0602061504y3507004dnf8b13d089d9fceba@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 7094 bytes --]
Arnaldo, (or anybody else)
I can get it working with the extra lock but not without... Comments
inline and at the end. Help much appreciated!
> Please leave the "extern"
>
Yep!
> I guess we don't need this lock, but instead use bh_lock_sock, check if
> there are users, look at ccid3_hc_tx_no_feedback_timer & ccid2_hc_tx_rto_expire
> (I left a comment even having fixed the problem, duh will fix).
I'm not sure what you mean by users here. Users of what? Can you explain
> sk_reset_timer() please, so that we make sure we have a reference count
> for the sock as its going to be on a timer
>
Will tidyup once get other problems sorted...
> No need for the {}, just one statement
Understand. Lazy when removing debugging...
> sk_eat_skb() later?
>
It would be sk_eat_skb in dccp_write_xmit for two reasons:
1) sk_eat_skb alters receive queue. This is write
2) Existing xmit doesn't seem to do anything like this. To me it looks
like the lower level does the kfree_skb...
>
> > + dp->dccps_xmit_lock = SPIN_LOCK_UNLOCKED;
>
> Not needed
Understand - will remove
Now I have attached two patches. acme1.diff is slightly tidied up
version of original patch and works with normal testing and netem
testing.
acme2.diff is an attempt to get rid of spinlock and use sock_lock as I
didn't think I needed bh_sock_lock as not receiving packets as that is
seemed aimed at that (stopping the interrupt driver trashing receive
queues...)
If I do away with spinlocks as per acme2.diff I get this:
Feb 21 14:37:56 localhost kernel: [17180168.280000] Debug: sleeping
function called from invalid context at net/core/sock.c:1327
Feb 21 14:37:56 localhost kernel: [17180168.280000] in_atomic():1,
irqs_disabled():0
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[show_trace+19/21] show_trace+0x13/0x15
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[dump_stack+22/26] dump_stack+0x16/0x1a
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[__might_sleep+135/143] __might_sleep+0x87/0x8f
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[lock_sock+26/158] lock_sock+0x1a/0x9e
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[pg0+411554706/1070261248] dccp_write_xmit+0x25/0x264 [dccp]
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[pg0+411555519/1070261248] dccp_write_xmit_timer+0xd/0x11 [dccp]
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[run_timer_softirq+296/387] run_timer_softirq+0x128/0x183
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[__do_softirq+66/144] __do_softirq+0x42/0x90
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[do_softirq+42/47] do_softirq+0x2a/0x2f
Feb 21 14:37:56 localhost kernel: [17180168.280000] [irq_exit+48/60]
irq_exit+0x30/0x3c
Feb 21 14:37:56 localhost kernel: [17180168.280000] [do_IRQ+72/84]
do_IRQ+0x48/0x54
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[common_interrupt+26/32] common_interrupt+0x1a/0x20
Feb 21 14:37:56 localhost kernel: [17180168.280000] [cpu_idle+71/115]
cpu_idle+0x47/0x73
Feb 21 14:37:56 localhost kernel: [17180168.280000] [_stext+55/60]
rest_init+0x37/0x3c
Feb 21 14:37:56 localhost kernel: [17180168.280000]
[start_kernel+639/641] start_kernel+0x27f/0x281
Feb 21 14:37:56 localhost kernel: [17180168.280000] [L6+0/2] 0xc0100199
which seems to be that it doesn't like lock_sock being called from a
timer as I read this. Can I not call lock_sock from a timer? When I
substituted lock_sock/release_sock for bh_lock_sock/bh_release_sock in
dccp_write_xmit (it doesn't call might_sleep) I lock my machine solid
with no output...
Feb 21 14:37:57 localhost kernel: [17180169.060000] scheduling while
atomic: ttcp_acme/0x00000101/11660
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[show_trace+19/21] show_trace+0x13/0x15
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[dump_stack+22/26] dump_stack+0x16/0x1a
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[schedule+67/1316] schedule+0x43/0x524
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[lock_sock+113/158] lock_sock+0x71/0x9e
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[pg0+411554706/1070261248] dccp_write_xmit+0x25/0x264 [dccp]
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[pg0+411555519/1070261248] dccp_write_xmit_timer+0xd/0x11 [dccp]
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[run_timer_softirq+296/387] run_timer_softirq+0x128/0x183
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[__do_softirq+66/144] __do_softirq+0x42/0x90
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[do_softirq+42/47] do_softirq+0x2a/0x2f
Feb 21 14:37:57 localhost kernel: [17180169.060000] [irq_exit+48/60]
irq_exit+0x30/0x3c
Feb 21 14:37:57 localhost kernel: [17180169.060000] [do_IRQ+72/84]
do_IRQ+0x48/0x54
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[common_interrupt+26/32] common_interrupt+0x1a/0x20
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[do_gettimeofday+20/148] do_gettimeofday+0x14/0x94
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[pg0+411550955/1070261248] dccp_timestamp+0x11/0x42 [dccp]
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[pg0+411872049/1070261248] ccid3_hc_tx_send_packet+0xeb/0x290
[dccp_ccid3]
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[pg0+411554738/1070261248] dccp_write_xmit+0x45/0x264 [dccp]
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[pg0+411558587/1070261248] dccp_sendmsg+0x11e/0x15f [dccp]
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[inet_sendmsg+52/64] inet_sendmsg+0x34/0x40
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[do_sock_write+145/153] do_sock_write+0x91/0x99
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[sock_aio_write+85/99] sock_aio_write+0x55/0x63
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[do_sync_write+159/208] do_sync_write+0x9f/0xd0
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[vfs_write+180/327] vfs_write+0xb4/0x147
Feb 21 14:37:57 localhost kernel: [17180169.060000] [sys_write+58/97]
sys_write+0x3a/0x61
Feb 21 14:37:57 localhost kernel: [17180169.060000]
[syscall_call+7/11] syscall_call+0x7/0xb
Here when I am transmitting a packet the timer fires because I go to
get the time and it causes an issue.....
acme2.diff doesn't work for me.
I can't see how to get this working without a transmit lock which
works perfectly for me. Are you able to tell me what I am doing wrong?
I personally can't see what I am doing wrong - it is just that
lock_sock isn't enough to prevent races which is why I need to put in
a transmit lock... the issue is really the timer firing. TCP doesn't
have the issue in quite this way as it uses ACK clocking in effect
rather than being time based like CCID3.
Comments/help really appreciated as I'm pulling my hair out and just
want to use my extra lock....
Ian
--
Ian McDonald
http://wand.net.nz/~iam4
WAND Network Research Group
Department of Computer Science
University of Waikato
New Zealand
[-- Attachment #2: acme1.diff --]
[-- Type: text/plain, Size: 7557 bytes --]
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 088529f..4a2f845 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -411,6 +411,8 @@ struct dccp_ackvec;
* @dccps_role - Role of this sock, one of %dccp_role
* @dccps_ndp_count - number of Non Data Packets since last data packet
* @dccps_hc_rx_ackvec - rx half connection ack vector
+ * @dccps_xmit_timer - timer for when CCID is not ready to send
+ * @dccps_xmit_lock - lock for transmitting
*/
struct dccp_sock {
/* inet_connection_sock has to be the first member of dccp_sock */
@@ -443,6 +445,8 @@ struct dccp_sock {
enum dccp_role dccps_role:2;
__u8 dccps_hc_rx_insert_options:1;
__u8 dccps_hc_tx_insert_options:1;
+ struct timer_list dccps_xmit_timer;
+ spinlock_t dccps_xmit_lock;
};
static inline struct dccp_sock *dccp_sk(const struct sock *sk)
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 93f26dd..ad38765 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -5,7 +5,7 @@
*
* An implementation of the DCCP protocol
* Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz>
+ * Copyright (c) 2005-6 Ian McDonald <imcdnzl@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as
@@ -126,7 +126,7 @@ extern void dccp_send_delayed_ack(struct
extern void dccp_send_sync(struct sock *sk, const u64 seq,
const enum dccp_pkt_type pkt_type);
-extern int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo);
+extern void dccp_write_xmit(struct sock *sk, int block);
extern void dccp_write_space(struct sock *sk);
extern void dccp_init_xmit_timers(struct sock *sk);
diff --git a/net/dccp/output.c b/net/dccp/output.c
index efd7ffb..efadaaa 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -2,7 +2,8 @@
* net/dccp/output.c
*
* An implementation of the DCCP protocol
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * Copyright (c) 2006 Ian McDonald <imcdnzl@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -191,7 +192,7 @@ static int dccp_wait_for_ccid(struct soc
while (1) {
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
+ if (sk->sk_err)
goto do_error;
if (!*timeo)
goto do_nonblock;
@@ -207,9 +208,11 @@ static int dccp_wait_for_ccid(struct soc
goto do_nonblock;
sk->sk_write_pending++;
+ spin_unlock(&dp->dccps_xmit_lock);
release_sock(sk);
*timeo -= schedule_timeout(delay);
lock_sock(sk);
+ spin_lock(&dp->dccps_xmit_lock);
sk->sk_write_pending--;
}
out:
@@ -227,37 +230,55 @@ do_interrupted:
goto out;
}
-int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo)
-{
- const struct dccp_sock *dp = dccp_sk(sk);
- int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb,
- skb->len);
+static void dccp_write_xmit_timer(unsigned long sk) {
+ dccp_write_xmit((struct sock *)sk,0);
+}
- if (err > 0)
- err = dccp_wait_for_ccid(sk, skb, timeo);
+void dccp_write_xmit(struct sock *sk, int block)
+{
+ struct dccp_sock *dp = dccp_sk(sk);
+ struct sk_buff *skb;
+ long timeo = 2000; /* FIXME imcdnzl - 2 second default */
- if (err == 0) {
- struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
- const int len = skb->len;
+ spin_lock(&dp->dccps_xmit_lock);
+
+ while ((skb = skb_peek(&sk->sk_write_queue))) {
+ int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb,
+ skb->len);
+
+ if (err > 0) {
+ if (likely(!block)) {
+ mod_timer(&dp->dccps_xmit_timer,
+ msecs_to_jiffies(err)+jiffies);
+ goto xmit_out;
+ } else
+ err = dccp_wait_for_ccid(sk, skb, &timeo);
+ }
- if (sk->sk_state == DCCP_PARTOPEN) {
- /* See 8.1.5. Handshake Completion */
- inet_csk_schedule_ack(sk);
- inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
+ skb_dequeue(&sk->sk_write_queue);
+ if (err == 0) {
+ struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
+ const int len = skb->len;
+
+ if (sk->sk_state == DCCP_PARTOPEN) {
+ /* See 8.1.5. Handshake Completion */
+ inet_csk_schedule_ack(sk);
+ inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
inet_csk(sk)->icsk_rto,
DCCP_RTO_MAX);
- dcb->dccpd_type = DCCP_PKT_DATAACK;
- } else if (dccp_ack_pending(sk))
- dcb->dccpd_type = DCCP_PKT_DATAACK;
- else
- dcb->dccpd_type = DCCP_PKT_DATA;
-
- err = dccp_transmit_skb(sk, skb);
- ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
- } else
- kfree_skb(skb);
-
- return err;
+ dcb->dccpd_type = DCCP_PKT_DATAACK;
+ } else if (dccp_ack_pending(sk))
+ dcb->dccpd_type = DCCP_PKT_DATAACK;
+ else
+ dcb->dccpd_type = DCCP_PKT_DATA;
+
+ err = dccp_transmit_skb(sk, skb);
+ ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
+ } else
+ kfree(skb);
+ }
+xmit_out:
+ spin_unlock(&dp->dccps_xmit_lock);
}
int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
@@ -396,6 +417,10 @@ static inline void dccp_connect_init(str
dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
icsk->icsk_retransmits = 0;
+ init_timer(&dp->dccps_xmit_timer);
+ dp->dccps_xmit_timer.data = (unsigned long)sk;
+ dp->dccps_xmit_timer.function = dccp_write_xmit_timer;
+ dp->dccps_xmit_lock = SPIN_LOCK_UNLOCKED;
}
int dccp_connect(struct sock *sk)
@@ -527,8 +552,10 @@ void dccp_send_close(struct sock *sk, co
DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ;
if (active) {
+ dccp_write_xmit(sk, 1);
dccp_skb_entail(sk, skb);
dccp_transmit_skb(sk, skb_clone(skb, prio));
+ /* FIXME do we need a retransmit timer here? */
} else
dccp_transmit_skb(sk, skb);
}
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 65b11ea..119ecc5 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -385,6 +385,7 @@ int dccp_sendmsg(struct kiocb *iocb, str
lock_sock(sk);
timeo = sock_sndtimeo(sk, noblock);
+ /* FIXME imcdnzl - we should be using timeo for memory allocation */
/*
* We have to use sk_stream_wait_connect here to set sk_write_pending,
@@ -407,19 +408,13 @@ int dccp_sendmsg(struct kiocb *iocb, str
if (rc != 0)
goto out_discard;
- rc = dccp_write_xmit(sk, skb, &timeo);
- /*
- * XXX we don't use sk_write_queue, so just discard the packet.
- * Current plan however is to _use_ sk_write_queue with
- * an algorith similar to tcp_sendmsg, where the main difference
- * is that in DCCP we have to respect packet boundaries, so
- * no coalescing of skbs.
- *
- * This bug was _quickly_ found & fixed by just looking at an OSTRA
- * generated callgraph 8) -acme
- */
+ skb_queue_tail(&sk->sk_write_queue, skb);
+ release_sock(sk);
+ dccp_write_xmit(sk,0);
+ goto out_end;
out_release:
release_sock(sk);
+out_end:
return rc ? : len;
out_discard:
kfree_skb(skb);
@@ -591,6 +586,7 @@ static int dccp_close_state(struct sock
void dccp_close(struct sock *sk, long timeout)
{
+ struct dccp_sock *dp = dccp_sk(sk);
struct sk_buff *skb;
lock_sock(sk);
@@ -606,6 +602,8 @@ void dccp_close(struct sock *sk, long ti
goto adjudge_to_death;
}
+ del_timer_sync(&dp->dccps_xmit_timer);
+
/*
* We need to flush the recv. buffs. We do this only on the
* descriptor close, not protocol-sourced closes, because the
[-- Attachment #3: acme2.diff --]
[-- Type: text/plain, Size: 7803 bytes --]
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 088529f..3604d1d 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -411,6 +411,8 @@ struct dccp_ackvec;
* @dccps_role - Role of this sock, one of %dccp_role
* @dccps_ndp_count - number of Non Data Packets since last data packet
* @dccps_hc_rx_ackvec - rx half connection ack vector
+ * @dccps_xmit_timer - timer for when CCID is not ready to send
+ * @dccps_xmit_lock - lock for transmitting
*/
struct dccp_sock {
/* inet_connection_sock has to be the first member of dccp_sock */
@@ -443,6 +445,8 @@ struct dccp_sock {
enum dccp_role dccps_role:2;
__u8 dccps_hc_rx_insert_options:1;
__u8 dccps_hc_tx_insert_options:1;
+ struct timer_list dccps_xmit_timer;
+// spinlock_t dccps_xmit_lock;
};
static inline struct dccp_sock *dccp_sk(const struct sock *sk)
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 93f26dd..ad38765 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -5,7 +5,7 @@
*
* An implementation of the DCCP protocol
* Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz>
+ * Copyright (c) 2005-6 Ian McDonald <imcdnzl@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as
@@ -126,7 +126,7 @@ extern void dccp_send_delayed_ack(struct
extern void dccp_send_sync(struct sock *sk, const u64 seq,
const enum dccp_pkt_type pkt_type);
-extern int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo);
+extern void dccp_write_xmit(struct sock *sk, int block);
extern void dccp_write_space(struct sock *sk);
extern void dccp_init_xmit_timers(struct sock *sk);
diff --git a/net/dccp/output.c b/net/dccp/output.c
index efd7ffb..f0e60af 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -2,7 +2,8 @@
* net/dccp/output.c
*
* An implementation of the DCCP protocol
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * Copyright (c) 2006 Ian McDonald <imcdnzl@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -191,7 +192,7 @@ static int dccp_wait_for_ccid(struct soc
while (1) {
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
+ if (sk->sk_err)
goto do_error;
if (!*timeo)
goto do_nonblock;
@@ -207,9 +208,12 @@ static int dccp_wait_for_ccid(struct soc
goto do_nonblock;
sk->sk_write_pending++;
+// spin_unlock(&dp->dccps_xmit_lock);
release_sock(sk);
+/* not using bh_lock as comes through dccp_close which uses lock_sock */
*timeo -= schedule_timeout(delay);
lock_sock(sk);
+// spin_lock(&dp->dccps_xmit_lock);
sk->sk_write_pending--;
}
out:
@@ -227,37 +231,63 @@ do_interrupted:
goto out;
}
-int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo)
+static void dccp_write_xmit_timer(unsigned long sk) {
+ dccp_write_xmit((struct sock *)sk,0);
+}
+
+void dccp_write_xmit(struct sock *sk, int block)
{
- const struct dccp_sock *dp = dccp_sk(sk);
- int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb,
- skb->len);
+ struct dccp_sock *dp = dccp_sk(sk);
+ struct sk_buff *skb;
+ long timeo = 2000; /* FIXME imcdnzl - 2 second default */
- if (err > 0)
- err = dccp_wait_for_ccid(sk, skb, timeo);
+// spin_lock(&dp->dccps_xmit_lock);
+//
+ if (!block)
+ lock_sock(sk);
- if (err == 0) {
- struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
- const int len = skb->len;
+ /* this is here because dccp_close locks the sock and
+ * we want to avoid deadlock */
+
+ while ((skb = skb_peek(&sk->sk_write_queue))) {
+ int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb,
+ skb->len);
+
+ if (err > 0) {
+ if (likely(!block)) {
+ mod_timer(&dp->dccps_xmit_timer,
+ msecs_to_jiffies(err)+jiffies);
+ goto xmit_out;
+ } else
+ err = dccp_wait_for_ccid(sk, skb, &timeo);
+ }
- if (sk->sk_state == DCCP_PARTOPEN) {
- /* See 8.1.5. Handshake Completion */
- inet_csk_schedule_ack(sk);
- inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
+ skb_dequeue(&sk->sk_write_queue);
+ if (err == 0) {
+ struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
+ const int len = skb->len;
+
+ if (sk->sk_state == DCCP_PARTOPEN) {
+ /* See 8.1.5. Handshake Completion */
+ inet_csk_schedule_ack(sk);
+ inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
inet_csk(sk)->icsk_rto,
DCCP_RTO_MAX);
- dcb->dccpd_type = DCCP_PKT_DATAACK;
- } else if (dccp_ack_pending(sk))
- dcb->dccpd_type = DCCP_PKT_DATAACK;
- else
- dcb->dccpd_type = DCCP_PKT_DATA;
-
- err = dccp_transmit_skb(sk, skb);
- ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
- } else
- kfree_skb(skb);
-
- return err;
+ dcb->dccpd_type = DCCP_PKT_DATAACK;
+ } else if (dccp_ack_pending(sk))
+ dcb->dccpd_type = DCCP_PKT_DATAACK;
+ else
+ dcb->dccpd_type = DCCP_PKT_DATA;
+
+ err = dccp_transmit_skb(sk, skb);
+ ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
+ } else
+ kfree(skb);
+ }
+xmit_out:
+ if (!block)
+ release_sock(sk);
+// spin_unlock(&dp->dccps_xmit_lock);
}
int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
@@ -396,6 +426,10 @@ static inline void dccp_connect_init(str
dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
icsk->icsk_retransmits = 0;
+ init_timer(&dp->dccps_xmit_timer);
+ dp->dccps_xmit_timer.data = (unsigned long)sk;
+ dp->dccps_xmit_timer.function = dccp_write_xmit_timer;
+// dp->dccps_xmit_lock = SPIN_LOCK_UNLOCKED;
}
int dccp_connect(struct sock *sk)
@@ -527,8 +561,10 @@ void dccp_send_close(struct sock *sk, co
DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ;
if (active) {
+ dccp_write_xmit(sk, 1);
dccp_skb_entail(sk, skb);
dccp_transmit_skb(sk, skb_clone(skb, prio));
+ /* FIXME do we need a retransmit timer here? */
} else
dccp_transmit_skb(sk, skb);
}
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 65b11ea..119ecc5 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -385,6 +385,7 @@ int dccp_sendmsg(struct kiocb *iocb, str
lock_sock(sk);
timeo = sock_sndtimeo(sk, noblock);
+ /* FIXME imcdnzl - we should be using timeo for memory allocation */
/*
* We have to use sk_stream_wait_connect here to set sk_write_pending,
@@ -407,19 +408,13 @@ int dccp_sendmsg(struct kiocb *iocb, str
if (rc != 0)
goto out_discard;
- rc = dccp_write_xmit(sk, skb, &timeo);
- /*
- * XXX we don't use sk_write_queue, so just discard the packet.
- * Current plan however is to _use_ sk_write_queue with
- * an algorith similar to tcp_sendmsg, where the main difference
- * is that in DCCP we have to respect packet boundaries, so
- * no coalescing of skbs.
- *
- * This bug was _quickly_ found & fixed by just looking at an OSTRA
- * generated callgraph 8) -acme
- */
+ skb_queue_tail(&sk->sk_write_queue, skb);
+ release_sock(sk);
+ dccp_write_xmit(sk,0);
+ goto out_end;
out_release:
release_sock(sk);
+out_end:
return rc ? : len;
out_discard:
kfree_skb(skb);
@@ -591,6 +586,7 @@ static int dccp_close_state(struct sock
void dccp_close(struct sock *sk, long timeout)
{
+ struct dccp_sock *dp = dccp_sk(sk);
struct sk_buff *skb;
lock_sock(sk);
@@ -606,6 +602,8 @@ void dccp_close(struct sock *sk, long ti
goto adjudge_to_death;
}
+ del_timer_sync(&dp->dccps_xmit_timer);
+
/*
* We need to flush the recv. buffs. We do this only on the
* descriptor close, not protocol-sourced closes, because the
^ permalink raw reply related
* Re: 2.6.16-rc4-mm1
From: Adrian Bunk @ 2006-02-20 21:09 UTC (permalink / raw)
To: dccp
In-Reply-To: <43F9CE18.10709@trash.net>
On Mon, Feb 20, 2006 at 05:56:47PM -0300, Arnaldo Carvalho de Melo wrote:
>...
> So perhaps something like what is done for the io schedulers, will study this...
The io schedulers solve this through "always build the noop scheduler"...
> - Arnaldo
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox