Skip to content

Commit

Permalink
[DCCP]: Prepare the AF agnostic core for the introduction of DCCPv6
Browse files Browse the repository at this point in the history
Basically exports a similar set of functions as the one exported by
the non-AF specific TCP code.

In the process moved some non-AF specific code from dccp_v4_connect to
dccp_connect_init and moved the checksum verification from
dccp_invalid_packet to dccp_v4_rcv, so as to use it in dccp_v6_rcv
too.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Arnaldo Carvalho de Melo authored and David S. Miller committed Jan 3, 2006
1 parent 34ca686 commit f21e68c
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 52 deletions.
22 changes: 22 additions & 0 deletions net/dccp/dccp.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ extern int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
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 void dccp_close(struct sock *sk, long timeout);
extern struct sk_buff *dccp_make_response(struct sock *sk,
struct dst_entry *dst,
Expand All @@ -238,6 +241,7 @@ extern struct sk_buff *dccp_make_reset(struct sock *sk,

extern int dccp_connect(struct sock *sk);
extern int dccp_disconnect(struct sock *sk, int flags);
extern void dccp_unhash(struct sock *sk);
extern int dccp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen);
extern int dccp_setsockopt(struct sock *sk, int level, int optname,
Expand All @@ -249,13 +253,31 @@ extern int dccp_recvmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len, int nonblock,
int flags, int *addr_len);
extern void dccp_shutdown(struct sock *sk, int how);
extern int inet_dccp_listen(struct socket *sock, int backlog);
extern unsigned int dccp_poll(struct file *file, struct socket *sock,
poll_table *wait);
extern void dccp_v4_send_check(struct sock *sk, int len,
struct sk_buff *skb);
extern int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
int addr_len);

extern int dccp_v4_checksum(const struct sk_buff *skb,
const u32 saddr, const u32 daddr);

extern int dccp_v4_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);

static inline int dccp_bad_service_code(const struct sock *sk,
const __u32 service)
{
const struct dccp_sock *dp = dccp_sk(sk);

if (dp->dccps_service == service)
return 0;
return !dccp_list_has_service(dp->dccps_service_list, service);
}

struct dccp_skb_cb {
__u8 dccpd_type:4;
Expand Down
4 changes: 4 additions & 0 deletions net/dccp/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
return 0;
}

EXPORT_SYMBOL_GPL(dccp_rcv_established);

static int dccp_rcv_request_sent_state_process(struct sock *sk,
struct sk_buff *skb,
const struct dccp_hdr *dh,
Expand Down Expand Up @@ -567,3 +569,5 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
}
return 0;
}

EXPORT_SYMBOL_GPL(dccp_rcv_state_process);
73 changes: 34 additions & 39 deletions net/dccp/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ static void dccp_v4_hash(struct sock *sk)
inet_hash(&dccp_hashinfo, sk);
}

static void dccp_v4_unhash(struct sock *sk)
void dccp_unhash(struct sock *sk)
{
inet_unhash(&dccp_hashinfo, sk);
}

EXPORT_SYMBOL_GPL(dccp_unhash);

/* called with local bh disabled */
static int __dccp_v4_check_established(struct sock *sk, const __u16 lport,
struct inet_timewait_sock **twp)
Expand Down Expand Up @@ -209,8 +211,7 @@ static int dccp_v4_hash_connect(struct sock *sk)
}
}

static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
int addr_len)
int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
struct inet_sock *inet = inet_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
Expand Down Expand Up @@ -288,16 +289,6 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
usin->sin_port);
dccp_update_gss(sk, dp->dccps_iss);

/*
* SWL and AWL are initially adjusted so that they are not less than
* the initial Sequence Numbers received and sent, respectively:
* SWL := max(GSR + 1 - floor(W/4), ISR),
* AWL := max(GSS - W' + 1, ISS).
* These adjustments MUST be applied only at the beginning of the
* connection.
*/
dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));

inet->id = dp->dccps_iss ^ jiffies;

err = dccp_connect(sk);
Expand All @@ -317,6 +308,8 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
goto out;
}

EXPORT_SYMBOL_GPL(dccp_v4_connect);

/*
* This routine does path mtu discovery as defined in RFC1191.
*/
Expand Down Expand Up @@ -608,14 +601,16 @@ void dccp_v4_err(struct sk_buff *skb, u32 info)
}

/* This routine computes an IPv4 DCCP checksum. */
static void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
{
const struct inet_sock *inet = inet_sk(sk);
struct dccp_hdr *dh = dccp_hdr(skb);

dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr);
}

EXPORT_SYMBOL_GPL(dccp_v4_send_check);

int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
{
struct sk_buff *skb;
Expand Down Expand Up @@ -651,16 +646,6 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk,
dccp_hdr(skb)->dccph_sport);
}

static inline int dccp_bad_service_code(const struct sock *sk,
const __u32 service)
{
const struct dccp_sock *dp = dccp_sk(sk);

if (dp->dccps_service == service)
return 0;
return !dccp_list_has_service(dp->dccps_service_list, service);
}

int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
struct inet_request_sock *ireq;
Expand All @@ -672,7 +657,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
const __u32 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;
struct dst_entry *dst = NULL;

/* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
if (((struct rtable *)skb->dst)->rt_flags &
Expand Down Expand Up @@ -713,7 +697,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
ireq = inet_rsk(req);
ireq->loc_addr = daddr;
ireq->rmt_addr = saddr;
/* FIXME: Merge Aristeu's option parsing code when ready */
req->rcv_wnd = 100; /* Fake, option parsing will get the
right value */
ireq->opt = NULL;
Expand All @@ -731,7 +714,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
dreq->dreq_iss = dccp_v4_init_sequence(sk, skb);
dreq->dreq_service = service;

if (dccp_v4_send_response(sk, req, dst))
if (dccp_v4_send_response(sk, req, NULL))
goto drop_and_free;

inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
Expand All @@ -748,6 +731,8 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
return -1;
}

EXPORT_SYMBOL_GPL(dccp_v4_conn_request);

/*
* The three way handshake has completed - we got a valid ACK or DATAACK -
* now create the new socket.
Expand Down Expand Up @@ -802,6 +787,8 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb,
return NULL;
}

EXPORT_SYMBOL_GPL(dccp_v4_request_recv_sock);

static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
{
const struct dccp_hdr *dh = dccp_hdr(skb);
Expand Down Expand Up @@ -1021,7 +1008,9 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
return 0;
}

static inline int dccp_invalid_packet(struct sk_buff *skb)
EXPORT_SYMBOL_GPL(dccp_v4_do_rcv);

int dccp_invalid_packet(struct sk_buff *skb)
{
const struct dccp_hdr *dh;

Expand Down Expand Up @@ -1075,17 +1064,11 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
return 1;
}

/* If the header checksum is incorrect, drop packet and return */
if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
skb->nh.iph->daddr) < 0) {
LIMIT_NETDEBUG(KERN_WARNING "DCCP: header checksum is "
"incorrect\n");
return 1;
}

return 0;
}

EXPORT_SYMBOL_GPL(dccp_invalid_packet);

/* this is called when real data arrives */
int dccp_v4_rcv(struct sk_buff *skb)
{
Expand All @@ -1098,6 +1081,14 @@ int dccp_v4_rcv(struct sk_buff *skb)
if (dccp_invalid_packet(skb))
goto discard_it;

/* If the header checksum is incorrect, drop packet and return */
if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
skb->nh.iph->daddr) < 0) {
LIMIT_NETDEBUG(KERN_WARNING "%s: incorrect header checksum\n",
__FUNCTION__);
goto discard_it;
}

dh = dccp_hdr(skb);

DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb);
Expand Down Expand Up @@ -1217,7 +1208,7 @@ struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
.sockaddr_len = sizeof(struct sockaddr_in),
};

static int dccp_v4_init_sock(struct sock *sk)
int dccp_v4_init_sock(struct sock *sk)
{
struct dccp_sock *dp = dccp_sk(sk);
static int dccp_ctl_socket_init = 1;
Expand Down Expand Up @@ -1270,7 +1261,9 @@ static int dccp_v4_init_sock(struct sock *sk)
return 0;
}

static int dccp_v4_destroy_sock(struct sock *sk)
EXPORT_SYMBOL_GPL(dccp_v4_init_sock);

int dccp_v4_destroy_sock(struct sock *sk)
{
struct dccp_sock *dp = dccp_sk(sk);

Expand Down Expand Up @@ -1303,6 +1296,8 @@ static int dccp_v4_destroy_sock(struct sock *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);
Expand Down Expand Up @@ -1331,7 +1326,7 @@ struct proto dccp_prot = {
.recvmsg = dccp_recvmsg,
.backlog_rcv = dccp_v4_do_rcv,
.hash = dccp_v4_hash,
.unhash = dccp_v4_unhash,
.unhash = dccp_unhash,
.accept = inet_csk_accept,
.get_port = dccp_v4_get_port,
.shutdown = dccp_shutdown,
Expand Down
8 changes: 8 additions & 0 deletions net/dccp/minisocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ struct inet_timewait_death_row dccp_death_row = {
(unsigned long)&dccp_death_row),
};

EXPORT_SYMBOL_GPL(dccp_death_row);

void dccp_time_wait(struct sock *sk, int state, int timeo)
{
struct inet_timewait_sock *tw = NULL;
Expand Down Expand Up @@ -170,6 +172,8 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
return newsk;
}

EXPORT_SYMBOL_GPL(dccp_create_openreq_child);

/*
* Process an incoming packet for RESPOND sockets represented
* as an request_sock.
Expand Down Expand Up @@ -236,6 +240,8 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
goto out;
}

EXPORT_SYMBOL_GPL(dccp_check_req);

/*
* Queue segment on the new socket if the new socket is active,
* otherwise we just shortcircuit this and continue with
Expand Down Expand Up @@ -266,3 +272,5 @@ int dccp_child_process(struct sock *parent, struct sock *child,
sock_put(child);
return ret;
}

EXPORT_SYMBOL_GPL(dccp_child_process);
27 changes: 17 additions & 10 deletions net/dccp/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,6 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
{
struct dccp_sock *dp = dccp_sk(sk);
/*
* FIXME: we really should be using the af_specific thing to support
* IPv6.
* mss_now = pmtu - tp->af_specific->net_header_len -
* sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext);
*/
int mss_now = (pmtu - inet_csk(sk)->icsk_af_ops->net_header_len -
sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext));

Expand All @@ -164,6 +158,8 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
return mss_now;
}

EXPORT_SYMBOL_GPL(dccp_sync_mss);

void dccp_write_space(struct sock *sk)
{
read_lock(&sk->sk_callback_lock);
Expand Down Expand Up @@ -319,6 +315,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
return skb;
}

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)

Expand Down Expand Up @@ -375,6 +373,7 @@ struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
*/
static inline void dccp_connect_init(struct sock *sk)
{
struct dccp_sock *dp = dccp_sk(sk);
struct dst_entry *dst = __sk_dst_get(sk);
struct inet_connection_sock *icsk = inet_csk(sk);

Expand All @@ -383,10 +382,16 @@ static inline void dccp_connect_init(struct sock *sk)

dccp_sync_mss(sk, dst_mtu(dst));

/*
* FIXME: set dp->{dccps_swh,dccps_swl}, with
* something like dccp_inc_seq
*/
dccp_update_gss(sk, dp->dccps_iss);
/*
* SWL and AWL are initially adjusted so that they are not less than
* the initial Sequence Numbers received and sent, respectively:
* SWL := max(GSR + 1 - floor(W/4), ISR),
* AWL := max(GSS - W' + 1, ISS).
* These adjustments MUST be applied only at the beginning of the
* connection.
*/
dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));

icsk->icsk_retransmits = 0;
}
Expand Down Expand Up @@ -418,6 +423,8 @@ int dccp_connect(struct sock *sk)
return 0;
}

EXPORT_SYMBOL_GPL(dccp_connect);

void dccp_send_ack(struct sock *sk)
{
/* If we have been reset, we may not send again. */
Expand Down
Loading

0 comments on commit f21e68c

Please sign in to comment.