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

Commit e7487c86 authored by Marcelo Ricardo Leitner's avatar Marcelo Ricardo Leitner Committed by David S. Miller
Browse files

sctp: avoid identifying address family many times for a chunk



Identifying address family operations during rx path is not something
expensive but it's ugly to the eye to have it done multiple times,
specially when we already validated it during initial rx processing.

This patch takes advantage of the now shared sctp_input_cb and make the
pointer to the operations readily available.

Signed-off-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1f45f78f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1104,6 +1104,7 @@ struct sctp_input_cb {
#endif
	} header;
	struct sctp_chunk *chunk;
	struct sctp_af *af;
};
#define SCTP_INPUT_CB(__skb)	((struct sctp_input_cb *)&((__skb)->cb[0]))

+1 −0
Original line number Diff line number Diff line
@@ -140,6 +140,7 @@ int sctp_rcv(struct sk_buff *skb)
	af = sctp_get_af_specific(family);
	if (unlikely(!af))
		goto discard_it;
	SCTP_INPUT_CB(skb)->af = af;

	/* Initialize local addresses for lookups. */
	af->from_skb(&src, skb, 1);
+1 −0
Original line number Diff line number Diff line
@@ -224,6 +224,7 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
				*head_cb = SCTP_INPUT_CB(chunk->head_skb);

			cb->chunk = head_cb->chunk;
			cb->af = head_cb->af;
		}
	}

+4 −16
Original line number Diff line number Diff line
@@ -108,14 +108,9 @@ static void sctp_control_set_owner_w(struct sctp_chunk *chunk)
/* What was the inbound interface for this chunk? */
int sctp_chunk_iif(const struct sctp_chunk *chunk)
{
	struct sctp_af *af;
	int iif = 0;

	af = sctp_get_af_specific(ipver2af(ip_hdr(chunk->skb)->version));
	if (af)
		iif = af->skb_iif(chunk->skb);
	struct sk_buff *skb = chunk->skb;

	return iif;
	return SCTP_INPUT_CB(skb)->af->skb_iif(skb);
}

/* RFC 2960 3.3.2 Initiation (INIT) (1)
@@ -1600,7 +1595,6 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
	struct sctp_association *asoc;
	struct sk_buff *skb;
	sctp_scope_t scope;
	struct sctp_af *af;

	/* Create the bare association.  */
	scope = sctp_scope(sctp_source(chunk));
@@ -1610,16 +1604,10 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
	asoc->temp = 1;
	skb = chunk->skb;
	/* Create an entry for the source address of the packet.  */
	af = sctp_get_af_specific(ipver2af(ip_hdr(skb)->version));
	if (unlikely(!af))
		goto fail;
	af->from_skb(&asoc->c.peer_addr, skb, 1);
	SCTP_INPUT_CB(skb)->af->from_skb(&asoc->c.peer_addr, skb, 1);

nodata:
	return asoc;

fail:
	sctp_association_free(asoc);
	return NULL;
}

/* Build a cookie representing asoc.
+2 −5
Original line number Diff line number Diff line
@@ -6119,13 +6119,10 @@ static int sctp_eat_data(const struct sctp_association *asoc,
	 */

	if (!chunk->ecn_ce_done) {
		struct sctp_af *af;
		struct sctp_af *af = SCTP_INPUT_CB(chunk->skb)->af;
		chunk->ecn_ce_done = 1;

		af = sctp_get_af_specific(
			ipver2af(ip_hdr(chunk->skb)->version));

		if (af && af->is_ce(sctp_gso_headskb(chunk->skb)) &&
		if (af->is_ce(sctp_gso_headskb(chunk->skb)) &&
		    asoc->peer.ecn_capable) {
			/* Do real work as sideffect. */
			sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE,