Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57cca05a authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller
Browse files

[DCCP]: Introduce dccp_ipv4_af_ops



And make the core DCCP code AF agnostic, just like TCP, now its time
to work on net/dccp/ipv6.c, we are close to the end!

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent af05dc93
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -329,7 +329,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
		dccp_set_state(sk, DCCP_PARTOPEN);

		/* Make sure socket is routed, for correct metrics. */
		inet_sk_rebuild_header(sk);
		icsk->icsk_af_ops->rebuild_header(sk);

		if (!sock_flag(sk, SOCK_DEAD)) {
			sk->sk_state_change(sk);
@@ -444,7 +444,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
	 */
	if (sk->sk_state == DCCP_LISTEN) {
		if (dh->dccph_type == DCCP_PKT_REQUEST) {
			if (dccp_v4_conn_request(sk, skb) < 0)
			if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
								    skb) < 0)
				return 1;

			/* FIXME: do congestion control initialization */
+23 −0
Original line number Diff line number Diff line
@@ -607,6 +607,15 @@ void dccp_v4_err(struct sk_buff *skb, u32 info)
	sock_put(sk);
}

/* This routine computes an IPv4 DCCP checksum. */
static 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);
}

int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
{
	struct sk_buff *skb;
@@ -1195,6 +1204,19 @@ int dccp_v4_rcv(struct sk_buff *skb)
	goto no_dccp_socket;
}

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,
	.conn_request	= dccp_v4_conn_request,
	.syn_recv_sock	= dccp_v4_request_recv_sock,
	.net_header_len	= sizeof(struct iphdr),
	.setsockopt	= ip_setsockopt,
	.getsockopt	= ip_getsockopt,
	.addr2sockaddr	= inet_csk_addr2sockaddr,
	.sockaddr_len	= sizeof(struct sockaddr_in),
};

static int dccp_v4_init_sock(struct sock *sk)
{
	struct dccp_sock *dp = dccp_sk(sk);
@@ -1240,6 +1262,7 @@ static int dccp_v4_init_sock(struct sock *sk)
	inet_csk(sk)->icsk_rto = DCCP_TIMEOUT_INIT;
	sk->sk_state = DCCP_CLOSED;
	sk->sk_write_space = dccp_write_space;
	inet_csk(sk)->icsk_af_ops = &dccp_ipv4_af_ops;
	dp->dccps_mss_cache = 536;
	dp->dccps_role = DCCP_ROLE_UNDEFINED;
	dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
+1 −1
Original line number Diff line number Diff line
@@ -214,7 +214,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
		goto drop;
	}

	child = dccp_v4_request_recv_sock(sk, skb, req, NULL);
	child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
	if (child == NULL)
		goto listen_overflow;

+6 −8
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
{
	if (likely(skb != NULL)) {
		const struct inet_sock *inet = inet_sk(sk);
		const struct inet_connection_sock *icsk = inet_csk(sk);
		struct dccp_sock *dp = dccp_sk(sk);
		struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
		struct dccp_hdr *dh;
@@ -108,8 +109,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
			break;
		}

		dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr,
						      inet->daddr);
		icsk->icsk_af_ops->send_check(sk, skb->len, skb);

		if (set_ack)
			dccp_event_ack_sent(sk);
@@ -117,7 +117,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
		DCCP_INC_STATS(DCCP_MIB_OUTSEGS);

		memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
		err = ip_queue_xmit(skb, 0);
		err = icsk->icsk_af_ops->queue_xmit(skb, 0);
		if (err <= 0)
			return err;

@@ -135,16 +135,14 @@ 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);
	int mss_now;

	/*
	 * 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);
	 */
	mss_now = pmtu - sizeof(struct iphdr) - 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));

	/* Now subtract optional transport overhead */
	mss_now -= dp->dccps_ext_header_len;
@@ -266,7 +264,7 @@ int dccp_write_xmit(struct sock *sk, struct sk_buff *skb, long *timeo)

int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
{
	if (inet_sk_rebuild_header(sk) != 0)
	if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0)
		return -EHOSTUNREACH; /* Routing failure or similar. */

	return dccp_transmit_skb(sk, (skb_cloned(skb) ?
+6 −3
Original line number Diff line number Diff line
@@ -254,7 +254,9 @@ int dccp_setsockopt(struct sock *sk, int level, int optname,
	int val;

	if (level != SOL_DCCP)
		return ip_setsockopt(sk, level, optname, optval, optlen);
		return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
							     optname, optval,
							     optlen);

	if (optlen < sizeof(int))
		return -EINVAL;
@@ -320,8 +322,9 @@ int dccp_getsockopt(struct sock *sk, int level, int optname,
	int val, len;

	if (level != SOL_DCCP)
		return ip_getsockopt(sk, level, optname, optval, optlen);

		return inet_csk(sk)->icsk_af_ops->getsockopt(sk, level,
							     optname, optval,
							     optlen);
	if (get_user(len, optlen))
		return -EFAULT;