Commit b2aa5e9d43a38dcdfa0878ed750cf32f98460278

Authored by Herbert Xu
Committed by David S. Miller
1 parent 716062fd4c

[IPSEC]: Store xfrm states in security path directly

As it is xfrm_input first collects a list of xfrm states on the stack
before storing them in the packet's security path just before it
returns.  For async crypto, this construction presents an obstacle
since we may need to leave the loop after each transform.

In fact, it's much easier to just skip the stack completely and always
store to the security path.  This is proven by the fact that this
patch actually shrinks the code.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 15 additions and 27 deletions Side-by-side Diff

net/xfrm/xfrm_input.c
... ... @@ -100,19 +100,29 @@
100 100 {
101 101 int err;
102 102 __be32 seq;
103   - struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
104 103 struct xfrm_state *x;
105   - int xfrm_nr = 0;
106 104 int decaps = 0;
107 105 unsigned int nhoff = XFRM_SPI_SKB_CB(skb)->nhoff;
108 106 unsigned int daddroff = XFRM_SPI_SKB_CB(skb)->daddroff;
109 107  
  108 + /* Allocate new secpath or COW existing one. */
  109 + if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
  110 + struct sec_path *sp;
  111 +
  112 + sp = secpath_dup(skb->sp);
  113 + if (!sp)
  114 + goto drop;
  115 + if (skb->sp)
  116 + secpath_put(skb->sp);
  117 + skb->sp = sp;
  118 + }
  119 +
110 120 seq = 0;
111 121 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
112 122 goto drop;
113 123  
114 124 do {
115   - if (xfrm_nr == XFRM_MAX_DEPTH)
  125 + if (skb->sp->len == XFRM_MAX_DEPTH)
116 126 goto drop;
117 127  
118 128 x = xfrm_state_lookup((xfrm_address_t *)
... ... @@ -121,6 +131,8 @@
121 131 if (x == NULL)
122 132 goto drop;
123 133  
  134 + skb->sp->xvec[skb->sp->len++] = x;
  135 +
124 136 spin_lock(&x->lock);
125 137 if (unlikely(x->km.state != XFRM_STATE_VALID))
126 138 goto drop_unlock;
... ... @@ -151,8 +163,6 @@
151 163  
152 164 spin_unlock(&x->lock);
153 165  
154   - xfrm_vec[xfrm_nr++] = x;
155   -
156 166 if (x->inner_mode->input(x, skb))
157 167 goto drop;
158 168  
... ... @@ -166,24 +176,6 @@
166 176 goto drop;
167 177 } while (!err);
168 178  
169   - /* Allocate new secpath or COW existing one. */
170   -
171   - if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
172   - struct sec_path *sp;
173   - sp = secpath_dup(skb->sp);
174   - if (!sp)
175   - goto drop;
176   - if (skb->sp)
177   - secpath_put(skb->sp);
178   - skb->sp = sp;
179   - }
180   - if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
181   - goto drop;
182   -
183   - memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
184   - xfrm_nr * sizeof(xfrm_vec[0]));
185   - skb->sp->len += xfrm_nr;
186   -
187 179 nf_reset(skb);
188 180  
189 181 if (decaps) {
190 182  
... ... @@ -197,11 +189,7 @@
197 189  
198 190 drop_unlock:
199 191 spin_unlock(&x->lock);
200   - xfrm_state_put(x);
201 192 drop:
202   - while (--xfrm_nr >= 0)
203   - xfrm_state_put(xfrm_vec[xfrm_nr]);
204   -
205 193 kfree_skb(skb);
206 194 return 0;
207 195 }