From patchwork Wed Aug 23 02:07:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 804725 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="klH2HEKc"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xcW6913D4z9s8V for ; Wed, 23 Aug 2017 12:07:45 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753073AbdHWCHg (ORCPT ); Tue, 22 Aug 2017 22:07:36 -0400 Received: from mail-pf0-f196.google.com ([209.85.192.196]:32856 "EHLO mail-pf0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753036AbdHWCHf (ORCPT ); Tue, 22 Aug 2017 22:07:35 -0400 Received: by mail-pf0-f196.google.com with SMTP id x137so366697pfd.0 for ; Tue, 22 Aug 2017 19:07:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=IdtCnCHPuznwT/bU5/ycjQSVcMzdLBkU061o61M+Vm0=; b=klH2HEKcxnp88lduOyKQzfPMDXWiS5sxXNTv+l7E5BvSBd4ItsTpITgssQXVi0Mpu6 Q2gwfI7LX/95kp0CyDmNyUuYh6W2o4/Y6OyckQwgGfxm9dPXKVKI2psA3qw0+2YwLWiV qFkDyVcVI5bklz1C7YAThRhMU4PF7hMmbwPlrOEzjEDH3PDoFAVsfyWZnP2sHGfQ2eGB OanYjwICFiak/AxB1bFpxl1pOeUSJ+gWDUpmxyoYXXNuepBaH8AsJguaS+tf4l93aEss x0mcr1TW+SX6siBUDgw52F2+52LJZ0y5IGXfqZ2+jGWf2WiPgu9hfPREhuEdzhBDSTIB yXkQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=IdtCnCHPuznwT/bU5/ycjQSVcMzdLBkU061o61M+Vm0=; b=dWSfJa5u3yXTwQgGu2r+ddFjqo16N49l4Ho7amwLaW6ZbFLgkjJJtWLloS0464KH0u L1p4UBC6hNNvylGrWCG4pG0Md5y5gA6WaAYH/VppPF84Y4n+/Rj2XV6GMJP8QdbFwNmH hGsxx4u51j7AGcgnS+Luo12nkdiLjbSzxzcVlDWGglxwJAGkrNxQOWTiyjT4TQGUsjzN wxiBYUTBAZatHUZOe9mBLnoTHt9Xz0FTF/A3PZ2AIjKyECYwH1c3eZrKkqrJU+7L3MCr +dgTpKhagv3sixHj2/IFJyHcJ84lcKxQLOGM17DVzbtFo9XZNKfONyzjRZPnU7h/d2La S9Aw== X-Gm-Message-State: AHYfb5iGMt68qdP6GTwoP80Q2uiNeWXgTEnjvI+kXNbDJoHUGasxjn4u NUTvKdcuN61St/yROvc= X-Received: by 10.99.180.8 with SMTP id s8mr1150997pgf.166.1503454054523; Tue, 22 Aug 2017 19:07:34 -0700 (PDT) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id a86sm382529pfe.181.2017.08.22.19.07.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Aug 2017 19:07:33 -0700 (PDT) From: Xin Long To: network dev Cc: davem@davemloft.net, Hannes Frederic Sowa Subject: [PATCH net-next] ipv4: do metrics match when looking up and deleting a route Date: Wed, 23 Aug 2017 10:07:26 +0800 Message-Id: <63b0473e7248f4931d46c45ac64e63b07bea6eeb.1503454046.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Now when ipv4 route inserts a fib_info, it memcmp fib_metrics. It means ipv4 route identifies one route also with metrics. But when removing a route, it tries to find the route without caring about the metrics. It will cause that the route with right metrics can't be removed. Thomas noticed this issue when doing the testing: 1. add: # ip route append 192.168.7.0/24 dev v window 1000 # ip route append 192.168.7.0/24 dev v window 1001 # ip route append 192.168.7.0/24 dev v window 1002 # ip route append 192.168.7.0/24 dev v window 1003 2. delete: # ip route delete 192.168.7.0/24 dev v window 1002 3. show: 192.168.7.0/24 proto boot scope link window 1001 192.168.7.0/24 proto boot scope link window 1002 192.168.7.0/24 proto boot scope link window 1003 The one with window 1002 wasn't deleted but the first one was. This patch is to do metrics match when looking up and deleting one route. Reported-by: Thomas Haller Signed-off-by: Xin Long Acked-by: Hannes Frederic Sowa --- net/ipv4/fib_lookup.h | 1 + net/ipv4/fib_semantics.c | 34 ++++++++++++++++++++++++++++++++++ net/ipv4/fib_trie.c | 3 ++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index 769ab87..5b2af19 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h @@ -32,6 +32,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, struct netlink_ext_ack *extack); int fib_nh_match(struct fib_config *cfg, struct fib_info *fi, struct netlink_ext_ack *extack); +bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi); int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, u32 tb_id, u8 type, __be32 dst, int dst_len, u8 tos, struct fib_info *fi, unsigned int); diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 394d800..57a5d48 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -696,6 +696,40 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi, return 0; } +bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi) +{ + struct nlattr *nla; + int remaining; + + if (!cfg->fc_mx) + return true; + + nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { + int type = nla_type(nla); + u32 val; + + if (!type) + continue; + if (type > RTAX_MAX) + return false; + + if (type == RTAX_CC_ALGO) { + char tmp[TCP_CA_NAME_MAX]; + bool ecn_ca = false; + + nla_strlcpy(tmp, nla, sizeof(tmp)); + val = tcp_ca_get_key_by_name(tmp, &ecn_ca); + } else { + val = nla_get_u32(nla); + } + + if (fi->fib_metrics->metrics[type - 1] != val) + return false; + } + + return true; +} + /* * Picture diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 1a6ffb0..c636650 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1563,7 +1563,8 @@ int fib_table_delete(struct net *net, struct fib_table *tb, fi->fib_prefsrc == cfg->fc_prefsrc) && (!cfg->fc_protocol || fi->fib_protocol == cfg->fc_protocol) && - fib_nh_match(cfg, fi, extack) == 0) { + fib_nh_match(cfg, fi, extack) == 0 && + fib_metrics_match(cfg, fi)) { fa_to_delete = fa; break; }