Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/klassert/ipsec-next

Conflicts:
	net/xfrm/xfrm_policy.c

Steffen Klassert says:

====================
This pull request has a merge conflict between commits be7928d
("net: xfrm: xfrm_policy: fix inline not at beginning of declaration") and
da7c224 ("net: xfrm: xfrm_policy: silence compiler warning") from
the net-next tree and commit 2f3ea9a ("xfrm: checkpatch erros with
inline keyword position") from the ipsec-next tree.

The version from net-next can be used, like it is done in linux-next.

1) Checkpatch cleanups, from Weilong Chen.

2) Fix lockdep complaints when pktgen is used with IPsec,
   from Fan Du.

3) Update pktgen to allow any combination of IPsec transport/tunnel mode
   and AH/ESP/IPcomp type, from Fan Du.

4) Make pktgen_dst_metrics static, Fengguang Wu.

5) Compile fix for pktgen when CONFIG_XFRM is not set,
   from Fan Du.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
davem330 committed Jan 14, 2014
2 parents 2afe02e + 6bae919 commit aef2b45
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 48 deletions.
15 changes: 15 additions & 0 deletions Documentation/networking/pktgen.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ Examples:
MPLS_RND, VID_RND, SVID_RND
QUEUE_MAP_RND # queue map random
QUEUE_MAP_CPU # queue map mirrors smp_processor_id()
IPSEC # Make IPsec encapsulation for packet

pgset spi SPI_VALUE Set specific SA used to transform packet.

pgset "udp_src_min 9" set UDP source port min, If < udp_src_max, then
cycle through the port range.
Expand Down Expand Up @@ -177,6 +179,18 @@ Note when adding devices to a specific CPU there good idea to also assign
/proc/irq/XX/smp_affinity so the TX-interrupts gets bound to the same CPU.
as this reduces cache bouncing when freeing skb's.

Enable IPsec
============
Default IPsec transformation with ESP encapsulation plus Transport mode
could be enabled by simply setting:

pgset "flag IPSEC"
pgset "flows 1"

To avoid breaking existing testbed scripts for using AH type and tunnel mode,
user could use "pgset spi SPI_VALUE" to specify which formal of transformation
to employ.


Current commands and configuration options
==========================================
Expand Down Expand Up @@ -225,6 +239,7 @@ flag
UDPDST_RND
MACSRC_RND
MACDST_RND
IPSEC

dst_min
dst_max
Expand Down
2 changes: 2 additions & 0 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1421,6 +1421,8 @@ struct xfrm_state *xfrm_stateonly_find(struct net *net, u32 mark,
xfrm_address_t *saddr,
unsigned short family,
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);
void xfrm_state_insert(struct xfrm_state *x);
int xfrm_state_add(struct xfrm_state *x);
Expand Down
80 changes: 66 additions & 14 deletions net/core/pktgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,9 @@ struct pktgen_dev {
#ifdef CONFIG_XFRM
__u8 ipsmode; /* IPSEC mode (config) */
__u8 ipsproto; /* IPSEC type (config) */
__u32 spi;
struct dst_entry dst;
struct dst_ops dstops;
#endif
char result[512];
};
Expand Down Expand Up @@ -654,8 +657,11 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
}

#ifdef CONFIG_XFRM
if (pkt_dev->flags & F_IPSEC_ON)
if (pkt_dev->flags & F_IPSEC_ON) {
seq_printf(seq, "IPSEC ");
if (pkt_dev->spi)
seq_printf(seq, "spi:%u", pkt_dev->spi);
}
#endif

if (pkt_dev->flags & F_MACSRC_RND)
Expand Down Expand Up @@ -1476,7 +1482,18 @@ static ssize_t pktgen_if_write(struct file *file,
sprintf(pg_result, "OK: flows=%u", pkt_dev->cflows);
return count;
}
#ifdef CONFIG_XFRM
if (!strcmp(name, "spi")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0)
return len;

i += len;
pkt_dev->spi = value;
sprintf(pg_result, "OK: spi=%u", pkt_dev->spi);
return count;
}
#endif
if (!strcmp(name, "flowlen")) {
len = num_arg(&user_buffer[i], 10, &value);
if (len < 0)
Expand Down Expand Up @@ -2233,13 +2250,21 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
struct xfrm_state *x = pkt_dev->flows[flow].x;
struct pktgen_net *pn = net_generic(dev_net(pkt_dev->odev), pg_net_id);
if (!x) {
/*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 (pkt_dev->spi) {
/* We need as quick as possible to find the right SA
* Searching with minimum criteria to archieve this.
*/
x = xfrm_state_lookup_byspi(pn->net, htonl(pkt_dev->spi), AF_INET);
} 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) {
pkt_dev->flows[flow].x = x;
set_pkt_overhead(pkt_dev);
Expand Down Expand Up @@ -2475,31 +2500,47 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)


#ifdef CONFIG_XFRM
static u32 pktgen_dst_metrics[RTAX_MAX + 1] = {

[RTAX_HOPLIMIT] = 0x5, /* Set a static hoplimit */
};

static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
{
struct xfrm_state *x = pkt_dev->flows[pkt_dev->curfl].x;
int err = 0;
struct net *net = dev_net(pkt_dev->odev);

if (!x)
return 0;
/* XXX: we dont support tunnel mode for now until
* we resolve the dst issue */
if (x->props.mode != XFRM_MODE_TRANSPORT)
if ((x->props.mode != XFRM_MODE_TRANSPORT) && (pkt_dev->spi == 0))
return 0;

spin_lock(&x->lock);
/* But when user specify an valid SPI, transformation
* supports both transport/tunnel mode + ESP/AH type.
*/
if ((x->props.mode == XFRM_MODE_TUNNEL) && (pkt_dev->spi != 0))
skb->_skb_refdst = (unsigned long)&pkt_dev->dst | SKB_DST_NOREF;

rcu_read_lock_bh();
err = x->outer_mode->output(x, skb);
if (err)
rcu_read_unlock_bh();
if (err) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEMODEERROR);
goto error;
}
err = x->type->output(x, skb);
if (err)
if (err) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEPROTOERROR);
goto error;

}
spin_lock_bh(&x->lock);
x->curlft.bytes += skb->len;
x->curlft.packets++;
spin_unlock_bh(&x->lock);
error:
spin_unlock(&x->lock);
return err;
}

Expand Down Expand Up @@ -3542,6 +3583,17 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
#ifdef CONFIG_XFRM
pkt_dev->ipsmode = XFRM_MODE_TRANSPORT;
pkt_dev->ipsproto = IPPROTO_ESP;

/* xfrm tunnel mode needs additional dst to extract outter
* ip header protocol/ttl/id field, here creat a phony one.
* instead of looking for a valid rt, which definitely hurting
* performance under such circumstance.
*/
pkt_dev->dstops.family = AF_INET;
pkt_dev->dst.dev = pkt_dev->odev;
dst_init_metrics(&pkt_dev->dst, pktgen_dst_metrics, false);
pkt_dev->dst.child = &pkt_dev->dst;
pkt_dev->dst.ops = &pkt_dev->dstops;
#endif

return add_dev_to_thread(t, pkt_dev);
Expand Down
6 changes: 3 additions & 3 deletions net/xfrm/xfrm_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
case IPPROTO_COMP:
if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr)))
return -EINVAL;
*spi = htonl(ntohs(*(__be16*)(skb_transport_header(skb) + 2)));
*spi = htonl(ntohs(*(__be16 *)(skb_transport_header(skb) + 2)));
*seq = 0;
return 0;
default:
Expand All @@ -77,8 +77,8 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
if (!pskb_may_pull(skb, hlen))
return -EINVAL;

*spi = *(__be32*)(skb_transport_header(skb) + offset);
*seq = *(__be32*)(skb_transport_header(skb) + offset_seq);
*spi = *(__be32 *)(skb_transport_header(skb) + offset);
*seq = *(__be32 *)(skb_transport_header(skb) + offset_seq);
return 0;
}

Expand Down
32 changes: 16 additions & 16 deletions net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ static inline unsigned long make_jiffies(long secs)

static void xfrm_policy_timer(unsigned long data)
{
struct xfrm_policy *xp = (struct xfrm_policy*)data;
struct xfrm_policy *xp = (struct xfrm_policy *)data;
unsigned long now = get_seconds();
long next = LONG_MAX;
int warn = 0;
Expand Down Expand Up @@ -1286,7 +1286,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family);
xfrm_address_t tmp;

for (nx=0, i = 0; i < policy->xfrm_nr; i++) {
for (nx = 0, i = 0; i < policy->xfrm_nr; i++) {
struct xfrm_state *x;
xfrm_address_t *remote = daddr;
xfrm_address_t *local = saddr;
Expand Down Expand Up @@ -1316,17 +1316,17 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
error = (x->km.state == XFRM_STATE_ERROR ?
-EINVAL : -EAGAIN);
xfrm_state_put(x);
}
else if (error == -ESRCH)
} else if (error == -ESRCH) {
error = -EAGAIN;
}

if (!tmpl->optional)
goto fail;
}
return nx;

fail:
for (nx--; nx>=0; nx--)
for (nx--; nx >= 0; nx--)
xfrm_state_put(xfrm[nx]);
return error;
}
Expand Down Expand Up @@ -1363,7 +1363,7 @@ xfrm_tmpl_resolve(struct xfrm_policy **pols, int npols, const struct flowi *fl,
return cnx;

fail:
for (cnx--; cnx>=0; cnx--)
for (cnx--; cnx >= 0; cnx--)
xfrm_state_put(tpp[cnx]);
return error;

Expand Down Expand Up @@ -1706,7 +1706,7 @@ static int xfrm_expand_policies(const struct flowi *fl, u16 family,
xfrm_pols_put(pols, *num_pols);
return PTR_ERR(pols[1]);
}
(*num_pols) ++;
(*num_pols)++;
(*num_xfrms) += pols[1]->xfrm_nr;
}
}
Expand Down Expand Up @@ -1760,7 +1760,7 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
}

xdst->num_pols = num_pols;
memcpy(xdst->pols, pols, sizeof(struct xfrm_policy*) * num_pols);
memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols);
xdst->policy_genid = atomic_read(&pols[0]->genid);

return xdst;
Expand Down Expand Up @@ -2029,7 +2029,7 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
}
xdst->num_pols = num_pols;
xdst->num_xfrms = num_xfrms;
memcpy(xdst->pols, pols, sizeof(struct xfrm_policy*) * num_pols);
memcpy(xdst->pols, pols, sizeof(struct xfrm_policy *) * num_pols);

dst_hold(&xdst->u.dst);
return &xdst->flo;
Expand Down Expand Up @@ -2138,7 +2138,7 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,

num_pols = xdst->num_pols;
num_xfrms = xdst->num_xfrms;
memcpy(pols, xdst->pols, sizeof(struct xfrm_policy*) * num_pols);
memcpy(pols, xdst->pols, sizeof(struct xfrm_policy *) * num_pols);
route = xdst->route;
}

Expand Down Expand Up @@ -2334,7 +2334,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
if (skb->sp) {
int i;

for (i=skb->sp->len-1; i>=0; i--) {
for (i = skb->sp->len-1; i >= 0; i--) {
struct xfrm_state *x = skb->sp->xvec[i];
if (!xfrm_selector_match(&x->sel, &fl, family)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH);
Expand Down Expand Up @@ -2380,7 +2380,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
pol->curlft.use_time = get_seconds();

pols[0] = pol;
npols ++;
npols++;
#ifdef CONFIG_XFRM_SUB_POLICY
if (pols[0]->type != XFRM_POLICY_TYPE_MAIN) {
pols[1] = xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN,
Expand All @@ -2392,7 +2392,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
return 0;
}
pols[1]->curlft.use_time = get_seconds();
npols ++;
npols++;
}
}
#endif
Expand Down Expand Up @@ -2989,7 +2989,7 @@ static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);

switch(sel->family) {
switch (sel->family) {
case AF_INET:
audit_log_format(audit_buf, " src=%pI4", &sel->saddr.a4);
if (sel->prefixlen_s != 32)
Expand Down Expand Up @@ -3066,8 +3066,8 @@ static bool xfrm_migrate_selector_match(const struct xfrm_selector *sel_cmp,
return false;
}

static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector *sel,
u8 dir, u8 type, struct net *net)
static struct xfrm_policy *xfrm_migrate_policy_find(const struct xfrm_selector *sel,
u8 dir, u8 type, struct net *net)
{
struct xfrm_policy *pol, *ret = NULL;
struct hlist_head *chain;
Expand Down
2 changes: 1 addition & 1 deletion net/xfrm/xfrm_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static int xfrm_statistics_seq_show(struct seq_file *seq, void *v)
{
struct net *net = seq->private;
int i;
for (i=0; xfrm_mib_list[i].name; i++)
for (i = 0; xfrm_mib_list[i].name; i++)
seq_printf(seq, "%-24s\t%lu\n", xfrm_mib_list[i].name,
snmp_fold_field((void __percpu **)
net->mib.xfrm_statistics,
Expand Down
Loading

0 comments on commit aef2b45

Please sign in to comment.