Bug 1480427 - RTM_NEWROUTE for `ip route add` and `ip route replace` considers route identity differently for Ipv6 gateway
RTM_NEWROUTE for `ip route add` and `ip route replace` considers route identi...
Status: NEW
Product: Fedora
Classification: Fedora
Component: kernel (Show other bugs)
26
Unspecified Unspecified
unspecified Severity unspecified
: ---
: ---
Assigned To: Kernel Maintainer List
Fedora Extras Quality Assurance
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2017-08-11 01:13 EDT by Thomas Haller
Modified: 2017-08-11 01:13 EDT (History)
8 users (show)

See Also:
Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed:
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Thomas Haller 2017-08-11 01:13:16 EDT
The issue seems reproducable on Fedora 26 kernel 4.11.11-300.fc26.x86_64, but not on RHEL (3.10.0-514.26.2.el7.x86_64).
 

BACKGROUND:
===========

When adding routes via RTM_NEWROUTE netlink message, nlmsg_flags like NLM_F_CREATE, NLM_F_REPLACE influence the behavior. These correspond to what iproute2 does with

  ip route add
  ip route replace
  ip route change
  ip route append
  ip route prepend

"add" and "replace" have a certain notion of duplicate routes, like

  ip route add 192.168.7.0/24 dev bond0 advmss 5
  ip route add 192.168.7.0/24 dev bond0 advmss 6
  # fails with EEXIST

which differs from what "append" and "prepend" considers equal. Note how

  ip route append 192.168.7.0/24 dev bond0 advmss 5
  ip route append 192.168.7.0/24 dev bond0 advmss 6

succeeds.


One could say, that `ip route append|prepend` treats "advmss" property as part of the idenity of a route, while `ip route add` won't.

See also bug 1337855.


Usually, `ip route add` and `ip route replace` have the same notion of identity. That means, 
  1) If not conflicting route exists, `ip route add` would succeed and the 
     outcome would be identical to `ip route replace`.
  2) If a conflicting route exists, `ip route add` would fail with EEXIST. In 
     that case, `ip route replace` would succeed actually replacing an existing 
     route.





REPRODUCER:
===========


#!/bin/bash

IP() {
    ip netns exec IPns ip "$@"
}
IPsetup() {
    ip netns del IPns
    ip netns add IPns
    IP link add type veth
    IP link set veth0 name v
    IP link set veth1 name w
    IP link set v up
    IP link set w up
    IP addr add 192.168.9.5/25 dev v
}


# setup:
IPsetup
IP route add 2001:db8:8086::1/128 dev v
IP route add 2001:db8:abad:c0de::/64 dev v via 2001:db8:8086::1

IP route add 2001:db8:abad:c0de::/64 dev v
# fails as expected: RTNETLINK answers: File exists

IP route replace 2001:db8:abad:c0de::/64 dev v
# succeeds as expected. However:

IP -6 -d route show dev v
#unicast 2001:db8:8086::1 proto boot scope global metric 1024 pref medium
#unicast 2001:db8:abad:c0de::/64 via 2001:db8:8086::1 proto boot scope global metric 1024 pref medium
#unicast 2001:db8:abad:c0de::/64 proto boot scope global metric 1024 pref medium
#unicast fe80::/64 proto kernel scope global metric 256 pref medium
#note how the route was not replaced. Instead, the result is like `ip route prepend`.





ISSUE:
======


note how `ip route add` fails, but `ip route replace` succeeds. However, contrary to 2) above, it does not replace an existing route, instead it behaves more like `ip route prepend`.

That means, the notion of route identity in above example differs between `ip route add` and `ip route replace`.

Instead, `ip route replace` should have replaced the existing route (like `ip route add` says that there is an existing route).

Note You need to log in before you can comment on or make changes to this bug.