diff options
author | Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> | 2016-07-13 14:08:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-13 21:10:14 -0400 |
commit | e7487c86dc5c4a528a7dbd9dc14f453a0de61a84 (patch) | |
tree | fee52720c9c4621d165294c8d48dff6326468c36 | |
parent | 1f45f78f8e511203f03138f2ccde3d2cf90d2cbf (diff) |
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: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/sctp/structs.h | 1 | ||||
-rw-r--r-- | net/sctp/input.c | 1 | ||||
-rw-r--r-- | net/sctp/inqueue.c | 1 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 20 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 7 |
5 files changed, 9 insertions, 21 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index f6f201de6fa4..ce93c4b10d26 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -1104,6 +1104,7 @@ struct sctp_input_cb { | |||
1104 | #endif | 1104 | #endif |
1105 | } header; | 1105 | } header; |
1106 | struct sctp_chunk *chunk; | 1106 | struct sctp_chunk *chunk; |
1107 | struct sctp_af *af; | ||
1107 | }; | 1108 | }; |
1108 | #define SCTP_INPUT_CB(__skb) ((struct sctp_input_cb *)&((__skb)->cb[0])) | 1109 | #define SCTP_INPUT_CB(__skb) ((struct sctp_input_cb *)&((__skb)->cb[0])) |
1109 | 1110 | ||
diff --git a/net/sctp/input.c b/net/sctp/input.c index 7a327ff71f08..30d72f7707b6 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -140,6 +140,7 @@ int sctp_rcv(struct sk_buff *skb) | |||
140 | af = sctp_get_af_specific(family); | 140 | af = sctp_get_af_specific(family); |
141 | if (unlikely(!af)) | 141 | if (unlikely(!af)) |
142 | goto discard_it; | 142 | goto discard_it; |
143 | SCTP_INPUT_CB(skb)->af = af; | ||
143 | 144 | ||
144 | /* Initialize local addresses for lookups. */ | 145 | /* Initialize local addresses for lookups. */ |
145 | af->from_skb(&src, skb, 1); | 146 | af->from_skb(&src, skb, 1); |
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index 147d975b0455..8fc773f9b59a 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c | |||
@@ -224,6 +224,7 @@ new_skb: | |||
224 | *head_cb = SCTP_INPUT_CB(chunk->head_skb); | 224 | *head_cb = SCTP_INPUT_CB(chunk->head_skb); |
225 | 225 | ||
226 | cb->chunk = head_cb->chunk; | 226 | cb->chunk = head_cb->chunk; |
227 | cb->af = head_cb->af; | ||
227 | } | 228 | } |
228 | } | 229 | } |
229 | 230 | ||
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 1c96f4740e67..8c77b87a8565 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -108,14 +108,9 @@ static void sctp_control_set_owner_w(struct sctp_chunk *chunk) | |||
108 | /* What was the inbound interface for this chunk? */ | 108 | /* What was the inbound interface for this chunk? */ |
109 | int sctp_chunk_iif(const struct sctp_chunk *chunk) | 109 | int sctp_chunk_iif(const struct sctp_chunk *chunk) |
110 | { | 110 | { |
111 | struct sctp_af *af; | 111 | struct sk_buff *skb = chunk->skb; |
112 | int iif = 0; | ||
113 | |||
114 | af = sctp_get_af_specific(ipver2af(ip_hdr(chunk->skb)->version)); | ||
115 | if (af) | ||
116 | iif = af->skb_iif(chunk->skb); | ||
117 | 112 | ||
118 | return iif; | 113 | return SCTP_INPUT_CB(skb)->af->skb_iif(skb); |
119 | } | 114 | } |
120 | 115 | ||
121 | /* RFC 2960 3.3.2 Initiation (INIT) (1) | 116 | /* RFC 2960 3.3.2 Initiation (INIT) (1) |
@@ -1600,7 +1595,6 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep, | |||
1600 | struct sctp_association *asoc; | 1595 | struct sctp_association *asoc; |
1601 | struct sk_buff *skb; | 1596 | struct sk_buff *skb; |
1602 | sctp_scope_t scope; | 1597 | sctp_scope_t scope; |
1603 | struct sctp_af *af; | ||
1604 | 1598 | ||
1605 | /* Create the bare association. */ | 1599 | /* Create the bare association. */ |
1606 | scope = sctp_scope(sctp_source(chunk)); | 1600 | scope = sctp_scope(sctp_source(chunk)); |
@@ -1610,16 +1604,10 @@ struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep, | |||
1610 | asoc->temp = 1; | 1604 | asoc->temp = 1; |
1611 | skb = chunk->skb; | 1605 | skb = chunk->skb; |
1612 | /* Create an entry for the source address of the packet. */ | 1606 | /* Create an entry for the source address of the packet. */ |
1613 | af = sctp_get_af_specific(ipver2af(ip_hdr(skb)->version)); | 1607 | SCTP_INPUT_CB(skb)->af->from_skb(&asoc->c.peer_addr, skb, 1); |
1614 | if (unlikely(!af)) | 1608 | |
1615 | goto fail; | ||
1616 | af->from_skb(&asoc->c.peer_addr, skb, 1); | ||
1617 | nodata: | 1609 | nodata: |
1618 | return asoc; | 1610 | return asoc; |
1619 | |||
1620 | fail: | ||
1621 | sctp_association_free(asoc); | ||
1622 | return NULL; | ||
1623 | } | 1611 | } |
1624 | 1612 | ||
1625 | /* Build a cookie representing asoc. | 1613 | /* Build a cookie representing asoc. |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 5aabf42065e2..b7c1f7f3c838 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -6119,13 +6119,10 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
6119 | */ | 6119 | */ |
6120 | 6120 | ||
6121 | if (!chunk->ecn_ce_done) { | 6121 | if (!chunk->ecn_ce_done) { |
6122 | struct sctp_af *af; | 6122 | struct sctp_af *af = SCTP_INPUT_CB(chunk->skb)->af; |
6123 | chunk->ecn_ce_done = 1; | 6123 | chunk->ecn_ce_done = 1; |
6124 | 6124 | ||
6125 | af = sctp_get_af_specific( | 6125 | if (af->is_ce(sctp_gso_headskb(chunk->skb)) && |
6126 | ipver2af(ip_hdr(chunk->skb)->version)); | ||
6127 | |||
6128 | if (af && af->is_ce(sctp_gso_headskb(chunk->skb)) && | ||
6129 | asoc->peer.ecn_capable) { | 6126 | asoc->peer.ecn_capable) { |
6130 | /* Do real work as sideffect. */ | 6127 | /* Do real work as sideffect. */ |
6131 | sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE, | 6128 | sctp_add_cmd_sf(commands, SCTP_CMD_ECN_CE, |