{pktgen, xfrm} Introduce xfrm_state_lookup_byspi for pktgen
Introduce xfrm_state_lookup_byspi to find user specified by custom from "pgset spi xxx". Using this scheme, any flow regardless its saddr/daddr could be transform by SA specified with configurable spi. Signed-off-by: Fan Du <fan.du@windriver.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
cf93d47ed4
commit
c454997e68
@ -1421,6 +1421,8 @@ struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark,
|
|||||||
xfrm_address_t *saddr,
|
xfrm_address_t *saddr,
|
||||||
unsigned short family,
|
unsigned short family,
|
||||||
u8 mode, u8 proto, u32 reqid);
|
u8 mode, u8 proto, u32 reqid);
|
||||||
|
struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
|
||||||
|
unsigned short family);
|
||||||
int xfrm_state_check_expire(struct xfrm_state *x);
|
int xfrm_state_check_expire(struct xfrm_state *x);
|
||||||
void xfrm_state_insert(struct xfrm_state *x);
|
void xfrm_state_insert(struct xfrm_state *x);
|
||||||
int xfrm_state_add(struct xfrm_state *x);
|
int xfrm_state_add(struct xfrm_state *x);
|
||||||
|
@ -2247,13 +2247,21 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
|
|||||||
struct xfrm_state *x = pkt_dev->flows[flow].x;
|
struct xfrm_state *x = pkt_dev->flows[flow].x;
|
||||||
struct pktgen_net *pn = net_generic(dev_net(pkt_dev->odev), pg_net_id);
|
struct pktgen_net *pn = net_generic(dev_net(pkt_dev->odev), pg_net_id);
|
||||||
if (!x) {
|
if (!x) {
|
||||||
/*slow path: we dont already have xfrm_state*/
|
|
||||||
x = xfrm_stateonly_find(pn->net, DUMMY_MARK,
|
if (pkt_dev->spi) {
|
||||||
(xfrm_address_t *)&pkt_dev->cur_daddr,
|
/* We need as quick as possible to find the right SA
|
||||||
(xfrm_address_t *)&pkt_dev->cur_saddr,
|
* Searching with minimum criteria to archieve this.
|
||||||
AF_INET,
|
*/
|
||||||
pkt_dev->ipsmode,
|
x = xfrm_state_lookup_byspi(pn->net, htonl(pkt_dev->spi), AF_INET);
|
||||||
pkt_dev->ipsproto, 0);
|
} else {
|
||||||
|
/* slow path: we dont already have xfrm_state */
|
||||||
|
x = xfrm_stateonly_find(pn->net, DUMMY_MARK,
|
||||||
|
(xfrm_address_t *)&pkt_dev->cur_daddr,
|
||||||
|
(xfrm_address_t *)&pkt_dev->cur_saddr,
|
||||||
|
AF_INET,
|
||||||
|
pkt_dev->ipsmode,
|
||||||
|
pkt_dev->ipsproto, 0);
|
||||||
|
}
|
||||||
if (x) {
|
if (x) {
|
||||||
pkt_dev->flows[flow].x = x;
|
pkt_dev->flows[flow].x = x;
|
||||||
set_pkt_overhead(pkt_dev);
|
set_pkt_overhead(pkt_dev);
|
||||||
|
@ -915,6 +915,28 @@ xfrm_stateonly_find(struct net *net, u32 mark,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(xfrm_stateonly_find);
|
EXPORT_SYMBOL(xfrm_stateonly_find);
|
||||||
|
|
||||||
|
struct xfrm_state *xfrm_state_lookup_byspi(struct net *net, __be32 spi,
|
||||||
|
unsigned short family)
|
||||||
|
{
|
||||||
|
struct xfrm_state *x;
|
||||||
|
struct xfrm_state_walk *w;
|
||||||
|
|
||||||
|
spin_lock_bh(&net->xfrm.xfrm_state_lock);
|
||||||
|
list_for_each_entry(w, &net->xfrm.state_all, all) {
|
||||||
|
x = container_of(w, struct xfrm_state, km);
|
||||||
|
if (x->props.family != family ||
|
||||||
|
x->id.spi != spi)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
spin_unlock_bh(&net->xfrm.xfrm_state_lock);
|
||||||
|
xfrm_state_hold(x);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&net->xfrm.xfrm_state_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(xfrm_state_lookup_byspi);
|
||||||
|
|
||||||
static void __xfrm_state_insert(struct xfrm_state *x)
|
static void __xfrm_state_insert(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct net *net = xs_net(x);
|
struct net *net = xs_net(x);
|
||||||
|
Loading…
Reference in New Issue
Block a user