Bug 207401 - vrf fwmark socket
Summary: vrf fwmark socket
Status: NEW
Alias: None
Product: Networking
Classification: Unclassified
Component: IPV4 (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Stephen Hemminger
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-04-22 12:37 UTC by Ma Shaohua
Modified: 2020-04-24 05:02 UTC (History)
1 user (show)

See Also:
Kernel Version: 5.5.11
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Ma Shaohua 2020-04-22 12:37:04 UTC
add rule:
#ip ru a fwmark 10000 table 10000 pref 900

and then add vrf and salve interface
#ip link add vrf-1 type vrf table 10
#ip link set dev vrf-1 up
#ip link set dev ens19 master vrf-1

write a program socket bind mark 10000 to match the rule
setsockopt(entry->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));

add ip and add route in table 10000
# ip a a 5.5.5.5/24 dev ens20
# ip r a 5.5.5.0/24 dev ens20 scope link table 10000 
if I set src addr, then can't add this route 

visit the server,success
#curl --interface 5.5.5.100
but if I use the mark, my program can't visit the server
kernel can't find my socket? return RST!
Comment 1 David Ahern 2020-04-23 02:12:30 UTC
your setup seems misconfigured.

Why is ens20 not enslaved to vrf-1?

Why are you using marks for routing and not the VRF FIB rule (l3mdev - added automatically since 4.8).
Comment 2 Ma Shaohua 2020-04-23 03:58:58 UTC
thank you for your reply!

ens20 is salved to vrf-1. I make mistake, write ens20 to ens19 in my description, sorry. But my operation is ens20.
ens19 and ens20 are all salved to vrf-1

I use this rule and table to solve one problem.
Problem is: if vrf-1 set two default route using different dev,
# ip r s vrf vrf-1
default via 4.4.4.25 dev ens19 metric 300
default via 5.5.5.25 dev ens20 metric 301
If I bind dev ens20, but if I visit some server use default route, 
for example:
#curl --interface ens20 7.7.7.7
kernel will select 4.4.4.25 for src addr.
So I want to set mark to select correct src addr and dev.
ens19 and ens20 have their own rule and table
In the table, they have their own default route and link route
like that:
[root@localhost ~]# ip ru
900:    from all fwmark 0x2710 lookup 10000
900:    from all fwmark 0x2711 lookup 10001
1000:   from all lookup [l3mdev-table]
32765:  from all lookup local
32766:  from all lookup main
32767:  from all lookup default
[root@localhost ~]# ip r s table 10000
default via 5.5.5.25 dev ens20
5.5.5.0/24 dev ens20 scope link
[root@localhost ~]# ip r s table 10001
default via 4.4.4.25 dev ens19
4.4.4.0/24 dev ens19 scope link
[root@localhost ~]#

I want to use personal rule and table in vrf, so I use SO_MARK and fwmark,
and then I found that kernel can't find the socket(set mark) under vrf in my operation. 

And I found that the route 
# ip r a 5.5.5.0/24 dev ens20 scope link table 10000 
I can't add the src option, if I add 'src 5.5.5.5', 
command return "Error: Invalid prefsrc address."
Comment 3 Ma Shaohua 2020-04-23 08:32:32 UTC
maybe I find the reason. In file inet_hashtables.c, function compute_score
should remove exact_dif paramter, udp has removed it.
https://github.com/torvalds/linux/commit/735453730a05391b4be97ad408b3bef07df13fe7
Comment 4 Ma Shaohua 2020-04-23 12:55:24 UTC
I must add one route first
# ip r a local 5.5.5.5 dev ens20 scope link src 5.5.5.5 table 10000
then I can run this command 
# ip r a 5.5.5.0/24 dev ens20 scope link src 5.5.5.5 table 10000
and then the table add this route correctly
Comment 5 Ma Shaohua 2020-04-24 02:34:26 UTC
type local should use scope host not scope link
Comment 6 David Ahern 2020-04-24 05:02:13 UTC
There are known issues with source address selection and ECMP / multiple route options as in your setup. The VRF design has a few more limitations.

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