aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/xfrm.h2
-rw-r--r--net/core/pktgen.c22
-rw-r--r--net/xfrm/xfrm_state.c22
3 files changed, 39 insertions, 7 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index b7635ef4d436..cd7c46ff6f1f 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1421,6 +1421,8 @@ struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark,
1421 xfrm_address_t *saddr, 1421 xfrm_address_t *saddr,
1422 unsigned short family, 1422 unsigned short family,
1423 u8 mode, u8 proto, u32 reqid); 1423 u8 mode, u8 proto, u32 reqid);
1424struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
1425 unsigned short family);
1424int xfrm_state_check_expire(struct xfrm_state *x); 1426int xfrm_state_check_expire(struct xfrm_state *x);
1425void xfrm_state_insert(struct xfrm_state *x); 1427void xfrm_state_insert(struct xfrm_state *x);
1426int xfrm_state_add(struct xfrm_state *x); 1428int xfrm_state_add(struct xfrm_state *x);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 628f7c572c6e..b553c36ea0ca 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2247,13 +2247,21 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
2247 struct xfrm_state *x = pkt_dev->flows[flow].x; 2247 struct xfrm_state *x = pkt_dev->flows[flow].x;
2248 struct pktgen_net *pn = net_generic(dev_net(pkt_dev->odev), pg_net_id); 2248 struct pktgen_net *pn = net_generic(dev_net(pkt_dev->odev), pg_net_id);
2249 if (!x) { 2249 if (!x) {
2250 /*slow path: we dont already have xfrm_state*/ 2250
2251 x = xfrm_stateonly_find(pn->net, DUMMY_MARK, 2251 if (pkt_dev->spi) {
2252 (xfrm_address_t *)&pkt_dev->cur_daddr, 2252 /* We need as quick as possible to find the right SA
2253 (xfrm_address_t *)&pkt_dev->cur_saddr, 2253 * Searching with minimum criteria to archieve this.
2254 AF_INET, 2254 */
2255 pkt_dev->ipsmode, 2255 x = xfrm_state_lookup_byspi(pn->net, htonl(pkt_dev->spi), AF_INET);
2256 pkt_dev->ipsproto, 0); 2256 } else {
2257 /* slow path: we dont already have xfrm_state */
2258 x = xfrm_stateonly_find(pn->net, DUMMY_MARK,
2259 (xfrm_address_t *)&pkt_dev->cur_daddr,
2260 (xfrm_address_t *)&pkt_dev->cur_saddr,
2261 AF_INET,
2262 pkt_dev->ipsmode,
2263 pkt_dev->ipsproto, 0);
2264 }
2257 if (x) { 2265 if (x) {
2258 pkt_dev->flows[flow].x = x; 2266 pkt_dev->flows[flow].x = x;
2259 set_pkt_overhead(pkt_dev); 2267 set_pkt_overhead(pkt_dev);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 300744094ad8..62181486ead8 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -915,6 +915,28 @@ xfrm_stateonly_find(struct net *net, u32 mark,
915} 915}
916EXPORT_SYMBOL(xfrm_stateonly_find); 916EXPORT_SYMBOL(xfrm_stateonly_find);
917 917
918struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
919 unsigned short family)
920{
921 struct xfrm_state *x;
922 struct xfrm_state_walk *w;
923
924 spin_lock_bh(&net->xfrm.xfrm_state_lock);
925 list_for_each_entry(w, &net->xfrm.state_all, all) {
926 x = container_of(w, struct xfrm_state, km);
927 if (x->props.family != family ||
928 x->id.spi != spi)
929 continue;
930
931 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
932 xfrm_state_hold(x);
933 return x;
934 }
935 spin_unlock_bh(&net->xfrm.xfrm_state_lock);
936 return NULL;
937}
938EXPORT_SYMBOL(xfrm_state_lookup_byspi);
939
918static void __xfrm_state_insert(struct xfrm_state *x) 940static void __xfrm_state_insert(struct xfrm_state *x)
919{ 941{
920 struct net *net = xs_net(x); 942 struct net *net = xs_net(x);