lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
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

Powered by Openwall GNU/*/Linux Powered by OpenVZ