Skip to content
  • Marcelo Ricardo Leitner's avatar
    sctp: fix src address selection if using secondary addresses · 0ca50d12
    Marcelo Ricardo Leitner authored
    
    
    In short, sctp is likely to incorrectly choose src address if socket is
    bound to secondary addresses. This patch fixes it by adding a new check
    that checks if such src address belongs to the interface that routing
    identified as output.
    
    This is enough to avoid rp_filter drops on remote peer.
    
    Details:
    
    Currently, sctp will do a routing attempt without specifying the src
    address and compare the returned value (preferred source) with the
    addresses that the socket is bound to. When using secondary addresses,
    this will not match.
    
    Then it will try specifying each of the addresses that the socket is
    bound to and re-routing, checking if that address is valid as src for
    that dst. Thing is, this check alone is weak:
    
    # ip r l
    192.168.100.0/24 dev eth1  proto kernel  scope link  src 192.168.100.149
    192.168.122.0/24 dev eth0  proto kernel  scope link  src 192.168.122.147
    
    # ip a l
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:15:18:6a brd ff:ff:ff:ff:ff:ff
        inet 192.168.122.147/24 brd 192.168.122.255 scope global dynamic eth0
           valid_lft 2160sec preferred_lft 2160sec
        inet 192.168.122.148/24 scope global secondary eth0
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:fe15:186a/64 scope link
           valid_lft forever preferred_lft forever
    3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:b3:91:46 brd ff:ff:ff:ff:ff:ff
        inet 192.168.100.149/24 brd 192.168.100.255 scope global dynamic eth1
           valid_lft 2162sec preferred_lft 2162sec
        inet 192.168.100.148/24 scope global secondary eth1
           valid_lft forever preferred_lft forever
        inet6 fe80::5054:ff:feb3:9146/64 scope link
           valid_lft forever preferred_lft forever
    4: ens9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:05:47:ee brd ff:ff:ff:ff:ff:ff
        inet6 fe80::5054:ff:fe05:47ee/64 scope link
           valid_lft forever preferred_lft forever
    
    # ip r g 192.168.100.193 from 192.168.122.148
    192.168.100.193 from 192.168.122.148 dev eth1
        cache
    
    Even if you specify an interface:
    
    # ip r g 192.168.100.193 from 192.168.122.148 oif eth1
    192.168.100.193 from 192.168.122.148 dev eth1
        cache
    
    Although this would be valid, peers using rp_filter will drop such
    packets as their src doesn't match the routes for that interface.
    
    Signed-off-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    0ca50d12