* [PATCH net-next 0/2] ila: Precompute checksums
@ 2015-08-19 3:21 Tom Herbert
2015-08-19 3:21 ` [PATCH net-next 1/2] lwt: Add cfg argumnt to build_state Tom Herbert
2015-08-19 3:21 ` [PATCH net-next 2/2] ila: Precompute checksum difference for translations Tom Herbert
0 siblings, 2 replies; 4+ messages in thread
From: Tom Herbert @ 2015-08-19 3:21 UTC (permalink / raw)
To: davem, roopa, netdev; +Cc: kernel-team
This patch set:
- Adds argument ot LWT build_state that holds a pointer to the fib
configuration being applied to the new route
- Adds support in ILA to precompute checksum difference for
performance optimization
Tom Herbert (2):
lwt: Add cfg argumnt to build_state
ila: Precompute checksum difference for translations
include/net/lwtunnel.h | 9 ++++++---
net/core/lwtunnel.c | 5 +++--
net/ipv4/fib_semantics.c | 14 +++++++++-----
net/ipv4/ip_tunnel_core.c | 3 ++-
net/ipv6/ila.c | 21 ++++++++++++++++++++-
net/ipv6/route.c | 3 ++-
net/mpls/mpls_iptunnel.c | 3 ++-
7 files changed, 44 insertions(+), 14 deletions(-)
--
1.8.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH net-next 1/2] lwt: Add cfg argumnt to build_state
2015-08-19 3:21 [PATCH net-next 0/2] ila: Precompute checksums Tom Herbert
@ 2015-08-19 3:21 ` Tom Herbert
2015-08-19 10:52 ` Jiri Benc
2015-08-19 3:21 ` [PATCH net-next 2/2] ila: Precompute checksum difference for translations Tom Herbert
1 sibling, 1 reply; 4+ messages in thread
From: Tom Herbert @ 2015-08-19 3:21 UTC (permalink / raw)
To: davem, roopa, netdev; +Cc: kernel-team
Add cfg and family arguments to lwt build state functions. cfg is a void
pointer and will either be a pointer to a fib_config or fib6_config
structure. The family parametter indicates which one (either AF_INET
or AF_INET6).
LWT encpasulation implementation may use the fib configuration to build
the LWT state.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
include/net/lwtunnel.h | 9 ++++++---
net/core/lwtunnel.c | 5 +++--
net/ipv4/fib_semantics.c | 14 +++++++++-----
net/ipv4/ip_tunnel_core.c | 3 ++-
net/ipv6/ila.c | 3 ++-
net/ipv6/route.c | 3 ++-
net/mpls/mpls_iptunnel.c | 3 ++-
7 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h
index e25b60e..9bf7e6a 100644
--- a/include/net/lwtunnel.h
+++ b/include/net/lwtunnel.h
@@ -26,7 +26,8 @@ struct lwtunnel_state {
struct lwtunnel_encap_ops {
int (*build_state)(struct net_device *dev, struct nlattr *encap,
- struct lwtunnel_state **ts);
+ struct lwtunnel_state **ts,
+ unsigned int family, const void *cfg);
int (*output)(struct sock *sk, struct sk_buff *skb);
int (*input)(struct sk_buff *skb);
int (*fill_encap)(struct sk_buff *skb,
@@ -75,7 +76,8 @@ int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
unsigned int num);
int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
struct nlattr *encap,
- struct lwtunnel_state **lws);
+ struct lwtunnel_state **lws,
+ unsigned int family, const void *cfg);
int lwtunnel_fill_encap(struct sk_buff *skb,
struct lwtunnel_state *lwtstate);
int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
@@ -123,7 +125,8 @@ static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
struct nlattr *encap,
- struct lwtunnel_state **lws)
+ struct lwtunnel_state **lws,
+ unsigned int family, const void *cfg)
{
return -EOPNOTSUPP;
}
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c
index 3331585..5ee3889 100644
--- a/net/core/lwtunnel.c
+++ b/net/core/lwtunnel.c
@@ -72,7 +72,8 @@ int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *ops,
EXPORT_SYMBOL(lwtunnel_encap_del_ops);
int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
- struct nlattr *encap, struct lwtunnel_state **lws)
+ struct nlattr *encap, struct lwtunnel_state **lws,
+ unsigned int family, const void *cfg)
{
const struct lwtunnel_encap_ops *ops;
int ret = -EINVAL;
@@ -85,7 +86,7 @@ int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
rcu_read_lock();
ops = rcu_dereference(lwtun_encaps[encap_type]);
if (likely(ops && ops->build_state))
- ret = ops->build_state(dev, encap, lws);
+ ret = ops->build_state(dev, encap, lws, family, cfg);
rcu_read_unlock();
return ret;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index c802585..408e037 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -511,7 +511,8 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
dev = __dev_get_by_index(net, cfg->fc_oif);
ret = lwtunnel_build_state(dev, nla_get_u16(
nla_entype),
- nla, &lwtstate);
+ nla, &lwtstate,
+ AF_INET, cfg);
if (ret)
goto errout;
nexthop_nh->nh_lwtstate =
@@ -535,7 +536,8 @@ errout:
int fib_encap_match(struct net *net, u16 encap_type,
struct nlattr *encap,
- int oif, const struct fib_nh *nh)
+ int oif, const struct fib_nh *nh,
+ const struct fib_config *cfg)
{
struct lwtunnel_state *lwtstate;
struct net_device *dev = NULL;
@@ -547,7 +549,8 @@ int fib_encap_match(struct net *net, u16 encap_type,
if (oif)
dev = __dev_get_by_index(net, oif);
ret = lwtunnel_build_state(dev, encap_type,
- encap, &lwtstate);
+ encap, &lwtstate,
+ AF_INET, cfg);
if (!ret)
return lwtunnel_cmp_encap(lwtstate, nh->nh_lwtstate);
@@ -569,7 +572,7 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
if (cfg->fc_encap) {
if (fib_encap_match(net, cfg->fc_encap_type,
cfg->fc_encap, cfg->fc_oif,
- fi->fib_nh))
+ fi->fib_nh, cfg))
return 1;
}
if ((!cfg->fc_oif || cfg->fc_oif == fi->fib_nh->nh_oif) &&
@@ -996,7 +999,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
if (cfg->fc_oif)
dev = __dev_get_by_index(net, cfg->fc_oif);
err = lwtunnel_build_state(dev, cfg->fc_encap_type,
- cfg->fc_encap, &lwtstate);
+ cfg->fc_encap, &lwtstate,
+ AF_INET, cfg);
if (err)
goto failure;
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index fd63196..0c95caa 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -204,7 +204,8 @@ static const struct nla_policy ip_tun_policy[LWTUNNEL_IP_MAX + 1] = {
};
static int ip_tun_build_state(struct net_device *dev, struct nlattr *attr,
- struct lwtunnel_state **ts)
+ struct lwtunnel_state **ts, unsigned int family,
+ const void *cfg)
{
struct ip_tunnel_info *tun_info;
struct lwtunnel_state *new_state;
diff --git a/net/ipv6/ila.c b/net/ipv6/ila.c
index 2540ab4..0b955e2 100644
--- a/net/ipv6/ila.c
+++ b/net/ipv6/ila.c
@@ -129,7 +129,8 @@ static struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
};
static int ila_build_state(struct net_device *dev, struct nlattr *nla,
- struct lwtunnel_state **ts)
+ struct lwtunnel_state **ts, unsigned int family,
+ const void *cfg)
{
struct ila_params *p;
struct nlattr *tb[ILA_ATTR_MAX + 1];
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index c373304..ff3a0f9 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1781,7 +1781,8 @@ int ip6_route_add(struct fib6_config *cfg)
struct lwtunnel_state *lwtstate;
err = lwtunnel_build_state(dev, cfg->fc_encap_type,
- cfg->fc_encap, &lwtstate);
+ cfg->fc_encap, &lwtstate,
+ AF_INET6, cfg);
if (err)
goto out;
rt->rt6i_lwtstate = lwtstate_get(lwtstate);
diff --git a/net/mpls/mpls_iptunnel.c b/net/mpls/mpls_iptunnel.c
index 276f8c9..4513d22 100644
--- a/net/mpls/mpls_iptunnel.c
+++ b/net/mpls/mpls_iptunnel.c
@@ -126,7 +126,8 @@ drop:
}
static int mpls_build_state(struct net_device *dev, struct nlattr *nla,
- struct lwtunnel_state **ts)
+ struct lwtunnel_state **ts, unsigned int family,
+ const void *cfg)
{
struct mpls_iptunnel_encap *tun_encap_info;
struct nlattr *tb[MPLS_IPTUNNEL_MAX + 1];
--
1.8.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH net-next 2/2] ila: Precompute checksum difference for translations
2015-08-19 3:21 [PATCH net-next 0/2] ila: Precompute checksums Tom Herbert
2015-08-19 3:21 ` [PATCH net-next 1/2] lwt: Add cfg argumnt to build_state Tom Herbert
@ 2015-08-19 3:21 ` Tom Herbert
1 sibling, 0 replies; 4+ messages in thread
From: Tom Herbert @ 2015-08-19 3:21 UTC (permalink / raw)
To: davem, roopa, netdev; +Cc: kernel-team
In the ILA build state for LWT compute the checksum difference to apply
to transport checksums that include the IPv6 pseudo header. The
difference is between the route destination (from fib6_config) and the
locator to write.
Signed-off-by: Tom Herbert <tom@herbertland.com>
---
net/ipv6/ila.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/net/ipv6/ila.c b/net/ipv6/ila.c
index 0b955e2..c78fef3 100644
--- a/net/ipv6/ila.c
+++ b/net/ipv6/ila.c
@@ -14,6 +14,8 @@
struct ila_params {
__be64 locator;
+ __be64 locator_match;
+ __wsum csum_diff;
};
static inline struct ila_params *ila_params_lwtunnel(
@@ -33,6 +35,9 @@ static inline __wsum compute_csum_diff8(const __be32 *from, const __be32 *to)
static inline __wsum get_csum_diff(struct ipv6hdr *ip6h, struct ila_params *p)
{
+ if (*(__be64 *)&ip6h->daddr == p->locator_match)
+ return p->csum_diff;
+ else
return compute_csum_diff8((__be32 *)&ip6h->daddr,
(__be32 *)&p->locator);
}
@@ -136,8 +141,12 @@ static int ila_build_state(struct net_device *dev, struct nlattr *nla,
struct nlattr *tb[ILA_ATTR_MAX + 1];
size_t encap_len = sizeof(*p);
struct lwtunnel_state *newts;
+ const struct fib6_config *cfg6 = cfg;
int ret;
+ if (family != AF_INET6)
+ return -EINVAL;
+
ret = nla_parse_nested(tb, ILA_ATTR_MAX, nla,
ila_nl_policy);
if (ret < 0)
@@ -155,6 +164,15 @@ static int ila_build_state(struct net_device *dev, struct nlattr *nla,
p->locator = (__force __be64)nla_get_u64(tb[ILA_ATTR_LOCATOR]);
+ if (cfg6->fc_dst_len > sizeof(__be64)) {
+ /* Precompute checksum difference for translation since we
+ * know both the old locator and the new one.
+ */
+ p->locator_match = *(__be64 *)&cfg6->fc_dst;
+ p->csum_diff = compute_csum_diff8(
+ (__be32 *)&p->locator_match, (__be32 *)&p->locator);
+ }
+
newts->type = LWTUNNEL_ENCAP_ILA;
newts->flags |= LWTUNNEL_STATE_OUTPUT_REDIRECT |
LWTUNNEL_STATE_INPUT_REDIRECT;
--
1.8.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH net-next 1/2] lwt: Add cfg argumnt to build_state
2015-08-19 3:21 ` [PATCH net-next 1/2] lwt: Add cfg argumnt to build_state Tom Herbert
@ 2015-08-19 10:52 ` Jiri Benc
0 siblings, 0 replies; 4+ messages in thread
From: Jiri Benc @ 2015-08-19 10:52 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, roopa, netdev, kernel-team
On Tue, 18 Aug 2015 20:21:10 -0700, Tom Herbert wrote:
> diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h
> index e25b60e..9bf7e6a 100644
> --- a/include/net/lwtunnel.h
> +++ b/include/net/lwtunnel.h
> @@ -26,7 +26,8 @@ struct lwtunnel_state {
>
> struct lwtunnel_encap_ops {
> int (*build_state)(struct net_device *dev, struct nlattr *encap,
> - struct lwtunnel_state **ts);
> + struct lwtunnel_state **ts,
> + unsigned int family, const void *cfg);
Could you please keep the output parameter as the last one?
(It might be better if build_state returned the newly allocated struct
instead and used pointer encoded errors but that's for a different
patch.)
Jiri
--
Jiri Benc
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-08-19 10:52 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-19 3:21 [PATCH net-next 0/2] ila: Precompute checksums Tom Herbert
2015-08-19 3:21 ` [PATCH net-next 1/2] lwt: Add cfg argumnt to build_state Tom Herbert
2015-08-19 10:52 ` Jiri Benc
2015-08-19 3:21 ` [PATCH net-next 2/2] ila: Precompute checksum difference for translations Tom Herbert
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).