[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAJieiUim_kE6XQz=24XfK72z2gsV54v9AxJEE5=pmpvPB5v93g@mail.gmail.com>
Date: Sun, 25 Feb 2018 09:51:09 -0800
From: Roopa Prabhu <roopa@...ulusnetworks.com>
To: Nikolay Aleksandrov <nikolay@...ulusnetworks.com>
Cc: David Miller <davem@...emloft.net>, netdev@...r.kernel.org,
David Ahern <dsa@...ulusnetworks.com>,
Ido Schimmel <idosch@...lanox.com>
Subject: Re: [PATCH net-next 5/5] ipv6: route: dissect flow in input path if
fib rules need it
On Sun, Feb 25, 2018 at 7:10 AM, Nikolay Aleksandrov
<nikolay@...ulusnetworks.com> wrote:
> On 25/02/18 07:44, Roopa Prabhu wrote:
>> From: Roopa Prabhu <roopa@...ulusnetworks.com>
>>
>> Dissect flow in fwd path if fib rules require it. Controlled by
>> a flag to avoid penatly for the common case. Flag is set when fib
>> rules with sport, dport and proto match that require flow dissect
>> are installed. Also passes the dissected hash keys to the multipath
>> hash function when applicable to avoid dissecting the flow again.
>> icmp packets will continue to use inner header for hash
>> calculations.
>>
>> Signed-off-by: Roopa Prabhu <roopa@...ulusnetworks.com>
>> ---
>> include/net/ip6_route.h | 3 ++-
>> include/net/netns/ipv6.h | 1 +
>> net/ipv6/fib6_rules.c | 5 +++++
>> net/ipv6/icmp.c | 2 +-
>> net/ipv6/route.c | 45 ++++++++++++++++++++++++++++++++++++---------
>> 5 files changed, 45 insertions(+), 11 deletions(-)
>>
>> diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
>> index 27d23a6..218f89c 100644
>> --- a/include/net/ip6_route.h
>> +++ b/include/net/ip6_route.h
>> @@ -127,7 +127,8 @@ static inline int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
>>
>> struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
>> const struct in6_addr *saddr, int oif, int flags);
>> -u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb);
>> +u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb,
>> + struct flow_keys *hkeys);
>>
>> struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct flowi6 *fl6);
>>
>> diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
>> index 987cc45..7aca00e 100644
>> --- a/include/net/netns/ipv6.h
>> +++ b/include/net/netns/ipv6.h
>> @@ -72,6 +72,7 @@ struct netns_ipv6 {
>> unsigned long ip6_rt_last_gc;
>> #ifdef CONFIG_IPV6_MULTIPLE_TABLES
>> bool fib6_has_custom_rules;
>> + bool fib6_rules_require_fldissect;
>> struct rt6_info *ip6_prohibit_entry;
>> struct rt6_info *ip6_blk_hole_entry;
>> struct fib6_table *fib6_local_tbl;
>> diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
>> index 678d664..e3a7861 100644
>> --- a/net/ipv6/fib6_rules.c
>> +++ b/net/ipv6/fib6_rules.c
>> @@ -267,6 +267,11 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
>> rule6->dst.plen = frh->dst_len;
>> rule6->tclass = frh->tos;
>>
>> + if (rule->ip_proto ||
>> + fib_rule_port_range_valid(&rule->sport_range) ||
>> + fib_rule_port_range_valid(&rule->dport_range))
>> + net->ipv6.fib6_rules_require_fldissect = true;
>> +
>> net->ipv6.fib6_has_custom_rules = true;
>> err = 0;
>> errout:
>> diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
>> index 4fa4f1b..b0778d3 100644
>> --- a/net/ipv6/icmp.c
>> +++ b/net/ipv6/icmp.c
>> @@ -522,7 +522,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
>> fl6.fl6_icmp_type = type;
>> fl6.fl6_icmp_code = code;
>> fl6.flowi6_uid = sock_net_uid(net, NULL);
>> - fl6.mp_hash = rt6_multipath_hash(&fl6, skb);
>> + fl6.mp_hash = rt6_multipath_hash(&fl6, skb, NULL);
>> security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
>>
>> sk = icmpv6_xmit_lock(net);
>> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
>> index aa709b6..778212b 100644
>> --- a/net/ipv6/route.c
>> +++ b/net/ipv6/route.c
>> @@ -460,7 +460,7 @@ static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
>> * case it will always be non-zero. Otherwise now is the time to do it.
>> */
>> if (!fl6->mp_hash)
>> - fl6->mp_hash = rt6_multipath_hash(fl6, NULL);
>> + fl6->mp_hash = rt6_multipath_hash(fl6, NULL, NULL);
>>
>> if (fl6->mp_hash <= atomic_read(&match->rt6i_nh_upper_bound))
>> return match;
>> @@ -1786,10 +1786,12 @@ struct dst_entry *ip6_route_input_lookup(struct net *net,
>> EXPORT_SYMBOL_GPL(ip6_route_input_lookup);
>>
>> static void ip6_multipath_l3_keys(const struct sk_buff *skb,
>> - struct flow_keys *keys)
>> + struct flow_keys *keys,
>> + struct flow_keys *flkeys)
>> {
>> const struct ipv6hdr *outer_iph = ipv6_hdr(skb);
>> const struct ipv6hdr *key_iph = outer_iph;
>> + struct flow_keys *_flkeys = flkeys;
>> const struct ipv6hdr *inner_iph;
>> const struct icmp6hdr *icmph;
>> struct ipv6hdr _inner_iph;
>> @@ -1811,22 +1813,31 @@ static void ip6_multipath_l3_keys(const struct sk_buff *skb,
>> goto out;
>>
>> key_iph = inner_iph;
>> + _flkeys = NULL;
>> out:
>> memset(keys, 0, sizeof(*keys));
>> keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
>> - keys->addrs.v6addrs.src = key_iph->saddr;
>> - keys->addrs.v6addrs.dst = key_iph->daddr;
>> - keys->tags.flow_label = ip6_flowinfo(key_iph);
>> - keys->basic.ip_proto = key_iph->nexthdr;
>> + if (_flkeys) {
>> + keys->addrs.v6addrs.src = _flkeys->addrs.v6addrs.src;
>> + keys->addrs.v6addrs.dst = _flkeys->addrs.v6addrs.dst;
>> + keys->tags.flow_label = _flkeys->tags.flow_label;
>> + keys->basic.ip_proto = _flkeys->basic.ip_proto;
>> + } else {
>> + keys->addrs.v6addrs.src = key_iph->saddr;
>> + keys->addrs.v6addrs.dst = key_iph->daddr;
>> + keys->tags.flow_label = ip6_flowinfo(key_iph);
>> + keys->basic.ip_proto = key_iph->nexthdr;
>> + }
>> }
>>
>> /* if skb is set it will be used and fl6 can be NULL */
>> -u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb)
>> +u32 rt6_multipath_hash(const struct flowi6 *fl6, const struct sk_buff *skb,
>> + struct flow_keys *flkeys)
>> {
>> struct flow_keys hash_keys;
>>
>> if (skb) {
>> - ip6_multipath_l3_keys(skb, &hash_keys);
>> + ip6_multipath_l3_keys(skb, &hash_keys, flkeys);
>> return flow_hash_from_keys(&hash_keys) >> 1;
>> }
>>
>> @@ -1847,12 +1858,27 @@ void ip6_route_input(struct sk_buff *skb)
>> .flowi6_mark = skb->mark,
>> .flowi6_proto = iph->nexthdr,
>> };
>> + struct flow_keys *flkeys = NULL, _flkeys;
>>
>> tun_info = skb_tunnel_info(skb);
>> if (tun_info && !(tun_info->mode & IP_TUNNEL_INFO_TX))
>> fl6.flowi6_tun_key.tun_id = tun_info->key.tun_id;
>> +
>> +#ifdef CONFIG_IPV6_MULTIPLE_TABLES
>> + if (net->ipv6.fib6_rules_require_fldissect) {
>> + unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
>> +
>> + memset(&_flkeys, 0, sizeof(_flkeys));
>
> Same here, skb_flow_dissect_flow_keys zeroes the flow_keys.
>
ack, will fix in v2
Powered by blists - more mailing lists