[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CALx6S35DpMWdLVWKSoRdsfROM7=A2p9pLi7n2fMtmqwhSEh5wQ@mail.gmail.com>
Date: Mon, 2 Oct 2017 12:36:33 -0700
From: Tom Herbert <tom@...bertland.com>
To: Simon Horman <simon.horman@...ronome.com>
Cc: David Miller <davem@...emloft.net>, Jiri Pirko <jiri@...lanox.com>,
Jamal Hadi Salim <jhs@...atatu.com>,
Cong Wang <xiyou.wangcong@...il.com>,
Linux Kernel Network Developers <netdev@...r.kernel.org>,
oss-drivers@...ronome.com
Subject: Re: [PATCH net-next 2/2] flow_dissector: dissect tunnel info
On Mon, Oct 2, 2017 at 1:41 AM, Simon Horman <simon.horman@...ronome.com> wrote:
> Move dissection of tunnel info from the flower classifier to the flow
> dissector where all other dissection occurs. This should not have any
> behavioural affect on other users of the flow dissector.
>
> Signed-off-by: Simon Horman <simon.horman@...ronome.com>
> Reviewed-by: Jakub Kicinski <jakub.kicinski@...ronome.com>
> ---
> net/core/flow_dissector.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++
> net/sched/cls_flower.c | 25 ------------
> 2 files changed, 100 insertions(+), 25 deletions(-)
>
> diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
> index 0a977373d003..1f5caafb4492 100644
> --- a/net/core/flow_dissector.c
> +++ b/net/core/flow_dissector.c
> @@ -5,6 +5,7 @@
> #include <linux/ipv6.h>
> #include <linux/if_vlan.h>
> #include <net/dsa.h>
> +#include <net/dst_metadata.h>
> #include <net/ip.h>
> #include <net/ipv6.h>
> #include <net/gre.h>
> @@ -115,6 +116,102 @@ __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
> }
> EXPORT_SYMBOL(__skb_flow_get_ports);
>
> +static void
> +skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type,
> + struct flow_dissector *flow_dissector,
> + void *target_container)
> +{
> + struct flow_dissector_key_control *ctrl;
> +
> + if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_CONTROL))
> + return;
> +
> + ctrl = skb_flow_dissector_target(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_CONTROL,
> + target_container);
> + ctrl->addr_type = type;
> +}
> +
> +static void
> +__skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
> + struct flow_dissector *flow_dissector,
> + void *target_container)
> +{
> + struct ip_tunnel_info *info;
> + struct ip_tunnel_key *key;
> +
> + /* A quick check to see if there might be something to do. */
> + if (!dissector_uses_key(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_KEYID) &&
> + !dissector_uses_key(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) &&
> + !dissector_uses_key(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) &&
> + !dissector_uses_key(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_CONTROL) &&
> + !dissector_uses_key(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_PORTS))
> + return;
This complex conditional is now in the path of every call to flow
dissector regardless of whether a classifier is enabled or tunnels
are. What does the assembly show in terms of number of branches? Can
we at least get this down to one check (might be a use case for
FLOW_DISSECTOR_F_FLOWER ;-) ), or even better use the static key when
encap or is enabled?
> +
> + info = skb_tunnel_info(skb);
> + if (!info)
> + return;
> +
> + key = &info->key;
> +
> + switch (ip_tunnel_info_af(info)) {
> + case AF_INET:
> + skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV4_ADDRS,
> + flow_dissector,
> + target_container);
> + if (dissector_uses_key(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
> + struct flow_dissector_key_ipv4_addrs *ipv4;
> +
> + ipv4 = skb_flow_dissector_target(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
> + target_container);
> + ipv4->src = key->u.ipv4.src;
> + ipv4->dst = key->u.ipv4.dst;
> + }
> + break;
> + case AF_INET6:
> + skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV6_ADDRS,
> + flow_dissector,
> + target_container);
> + if (dissector_uses_key(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
> + struct flow_dissector_key_ipv6_addrs *ipv6;
> +
> + ipv6 = skb_flow_dissector_target(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS,
> + target_container);
> + ipv6->src = key->u.ipv6.src;
> + ipv6->dst = key->u.ipv6.dst;
> + }
> + break;
> + }
> +
> + if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
> + struct flow_dissector_key_keyid *keyid;
> +
> + keyid = skb_flow_dissector_target(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_KEYID,
> + target_container);
> + keyid->keyid = tunnel_id_to_key32(key->tun_id);
> + }
> +
> + if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_PORTS)) {
> + struct flow_dissector_key_ports *tp;
> +
> + tp = skb_flow_dissector_target(flow_dissector,
> + FLOW_DISSECTOR_KEY_ENC_PORTS,
> + target_container);
> + tp->src = key->tp_src;
> + tp->dst = key->tp_dst;
> + }
> +}
> +
> static enum flow_dissect_ret
> __skb_flow_dissect_mpls(const struct sk_buff *skb,
> struct flow_dissector *flow_dissector,
> @@ -478,6 +575,9 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
> FLOW_DISSECTOR_KEY_BASIC,
> target_container);
>
> + __skb_flow_dissect_tunnel_info(skb, flow_dissector,
> + target_container);
> +
> if (dissector_uses_key(flow_dissector,
> FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
> struct ethhdr *eth = eth_hdr(skb);
> diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
> index d230cb4c8094..db831ac708f6 100644
> --- a/net/sched/cls_flower.c
> +++ b/net/sched/cls_flower.c
> @@ -152,37 +152,12 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
> struct cls_fl_filter *f;
> struct fl_flow_key skb_key;
> struct fl_flow_key skb_mkey;
> - struct ip_tunnel_info *info;
>
> if (!atomic_read(&head->ht.nelems))
> return -1;
>
> fl_clear_masked_range(&skb_key, &head->mask);
>
> - info = skb_tunnel_info(skb);
> - if (info) {
> - struct ip_tunnel_key *key = &info->key;
> -
> - switch (ip_tunnel_info_af(info)) {
> - case AF_INET:
> - skb_key.enc_control.addr_type =
> - FLOW_DISSECTOR_KEY_IPV4_ADDRS;
> - skb_key.enc_ipv4.src = key->u.ipv4.src;
> - skb_key.enc_ipv4.dst = key->u.ipv4.dst;
> - break;
> - case AF_INET6:
> - skb_key.enc_control.addr_type =
> - FLOW_DISSECTOR_KEY_IPV6_ADDRS;
> - skb_key.enc_ipv6.src = key->u.ipv6.src;
> - skb_key.enc_ipv6.dst = key->u.ipv6.dst;
> - break;
> - }
> -
> - skb_key.enc_key_id.keyid = tunnel_id_to_key32(key->tun_id);
> - skb_key.enc_tp.src = key->tp_src;
> - skb_key.enc_tp.dst = key->tp_dst;
> - }
> -
> skb_key.indev_ifindex = skb->skb_iif;
> /* skb_flow_dissect() does not set n_proto in case an unknown protocol,
> * so do it rather here.
> --
> 2.1.4
>
Powered by blists - more mailing lists