Skip to content

Commit e67e017

Browse files
committed
Merge: vrf: stable backports for 10.1 phase 1
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/792 JIRA: https://issues.redhat.com/browse/RHEL-84551 Depends: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/752 Signed-off-by: Antoine Tenart <atenart@redhat.com> Approved-by: Xin Long <lxin@redhat.com> Approved-by: Hangbin Liu <haliu@redhat.com> Merged-by: Julio Faracco <jfaracco@redhat.com>
2 parents b4defcf + 264b5f8 commit e67e017

File tree

5 files changed

+74
-10
lines changed

5 files changed

+74
-10
lines changed

include/net/fib_rules.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ struct fib_rule {
4343
struct fib_kuid_range uid_range;
4444
struct fib_rule_port_range sport_range;
4545
struct fib_rule_port_range dport_range;
46+
u8 iif_is_l3_master;
47+
u8 oif_is_l3_master;
4648
struct rcu_head rcu;
4749
};
4850

include/net/flow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct flowi_common {
3838
__u8 flowic_flags;
3939
#define FLOWI_FLAG_ANYSRC 0x01
4040
#define FLOWI_FLAG_KNOWN_NH 0x02
41+
#define FLOWI_FLAG_L3MDEV_OIF 0x04
4142
__u32 flowic_secid;
4243
kuid_t flowic_uid;
4344
__u32 flowic_multipath_hash;

include/net/l3mdev.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net,
5959
int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
6060
struct fib_lookup_arg *arg);
6161

62+
static inline
63+
bool l3mdev_fib_rule_iif_match(const struct flowi *fl, int iifindex)
64+
{
65+
return !(fl->flowi_flags & FLOWI_FLAG_L3MDEV_OIF) &&
66+
fl->flowi_l3mdev == iifindex;
67+
}
68+
69+
static inline
70+
bool l3mdev_fib_rule_oif_match(const struct flowi *fl, int oifindex)
71+
{
72+
return fl->flowi_flags & FLOWI_FLAG_L3MDEV_OIF &&
73+
fl->flowi_l3mdev == oifindex;
74+
}
75+
6276
void l3mdev_update_flow(struct net *net, struct flowi *fl);
6377

6478
int l3mdev_master_ifindex_rcu(const struct net_device *dev);
@@ -78,7 +92,7 @@ static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
7892
struct net_device *dev;
7993
int rc = 0;
8094

81-
if (likely(ifindex)) {
95+
if (ifindex) {
8296
rcu_read_lock();
8397

8498
dev = dev_get_by_index_rcu(net, ifindex);
@@ -327,6 +341,19 @@ int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
327341
{
328342
return 1;
329343
}
344+
345+
static inline
346+
bool l3mdev_fib_rule_iif_match(const struct flowi *fl, int iifindex)
347+
{
348+
return false;
349+
}
350+
351+
static inline
352+
bool l3mdev_fib_rule_oif_match(const struct flowi *fl, int oifindex)
353+
{
354+
return false;
355+
}
356+
330357
static inline
331358
void l3mdev_update_flow(struct net *net, struct flowi *fl)
332359
{

net/core/fib_rules.c

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -256,18 +256,36 @@ static int nla_put_port_range(struct sk_buff *skb, int attrtype,
256256
return nla_put(skb, attrtype, sizeof(*range), range);
257257
}
258258

259+
static bool fib_rule_iif_match(const struct fib_rule *rule, int iifindex,
260+
const struct flowi *fl)
261+
{
262+
u8 iif_is_l3_master = READ_ONCE(rule->iif_is_l3_master);
263+
264+
return iif_is_l3_master ? l3mdev_fib_rule_iif_match(fl, iifindex) :
265+
fl->flowi_iif == iifindex;
266+
}
267+
268+
static bool fib_rule_oif_match(const struct fib_rule *rule, int oifindex,
269+
const struct flowi *fl)
270+
{
271+
u8 oif_is_l3_master = READ_ONCE(rule->oif_is_l3_master);
272+
273+
return oif_is_l3_master ? l3mdev_fib_rule_oif_match(fl, oifindex) :
274+
fl->flowi_oif == oifindex;
275+
}
276+
259277
static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
260278
struct flowi *fl, int flags,
261279
struct fib_lookup_arg *arg)
262280
{
263281
int iifindex, oifindex, ret = 0;
264282

265283
iifindex = READ_ONCE(rule->iifindex);
266-
if (iifindex && (iifindex != fl->flowi_iif))
284+
if (iifindex && !fib_rule_iif_match(rule, iifindex, fl))
267285
goto out;
268286

269287
oifindex = READ_ONCE(rule->oifindex);
270-
if (oifindex && (oifindex != fl->flowi_oif))
288+
if (oifindex && !fib_rule_oif_match(rule, oifindex, fl))
271289
goto out;
272290

273291
if ((rule->mark ^ fl->flowi_mark) & rule->mark_mask)
@@ -567,8 +585,10 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
567585
nlrule->iifindex = -1;
568586
nla_strscpy(nlrule->iifname, tb[FRA_IIFNAME], IFNAMSIZ);
569587
dev = __dev_get_by_name(net, nlrule->iifname);
570-
if (dev)
588+
if (dev) {
571589
nlrule->iifindex = dev->ifindex;
590+
nlrule->iif_is_l3_master = netif_is_l3_master(dev);
591+
}
572592
}
573593

574594
if (tb[FRA_OIFNAME]) {
@@ -577,8 +597,10 @@ static int fib_nl2rule(struct sk_buff *skb, struct nlmsghdr *nlh,
577597
nlrule->oifindex = -1;
578598
nla_strscpy(nlrule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
579599
dev = __dev_get_by_name(net, nlrule->oifname);
580-
if (dev)
600+
if (dev) {
581601
nlrule->oifindex = dev->ifindex;
602+
nlrule->oif_is_l3_master = netif_is_l3_master(dev);
603+
}
582604
}
583605

584606
if (tb[FRA_FWMARK]) {
@@ -1218,11 +1240,17 @@ static void attach_rules(struct list_head *rules, struct net_device *dev)
12181240

12191241
list_for_each_entry(rule, rules, list) {
12201242
if (rule->iifindex == -1 &&
1221-
strcmp(dev->name, rule->iifname) == 0)
1243+
strcmp(dev->name, rule->iifname) == 0) {
12221244
WRITE_ONCE(rule->iifindex, dev->ifindex);
1245+
WRITE_ONCE(rule->iif_is_l3_master,
1246+
netif_is_l3_master(dev));
1247+
}
12231248
if (rule->oifindex == -1 &&
1224-
strcmp(dev->name, rule->oifname) == 0)
1249+
strcmp(dev->name, rule->oifname) == 0) {
12251250
WRITE_ONCE(rule->oifindex, dev->ifindex);
1251+
WRITE_ONCE(rule->oif_is_l3_master,
1252+
netif_is_l3_master(dev));
1253+
}
12261254
}
12271255
}
12281256

@@ -1231,10 +1259,14 @@ static void detach_rules(struct list_head *rules, struct net_device *dev)
12311259
struct fib_rule *rule;
12321260

12331261
list_for_each_entry(rule, rules, list) {
1234-
if (rule->iifindex == dev->ifindex)
1262+
if (rule->iifindex == dev->ifindex) {
12351263
WRITE_ONCE(rule->iifindex, -1);
1236-
if (rule->oifindex == dev->ifindex)
1264+
WRITE_ONCE(rule->iif_is_l3_master, false);
1265+
}
1266+
if (rule->oifindex == dev->ifindex) {
12371267
WRITE_ONCE(rule->oifindex, -1);
1268+
WRITE_ONCE(rule->oif_is_l3_master, false);
1269+
}
12381270
}
12391271
}
12401272

net/l3mdev/l3mdev.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,10 @@ void l3mdev_update_flow(struct net *net, struct flowi *fl)
277277
if (fl->flowi_oif) {
278278
dev = dev_get_by_index_rcu(net, fl->flowi_oif);
279279
if (dev) {
280-
if (!fl->flowi_l3mdev)
280+
if (!fl->flowi_l3mdev) {
281281
fl->flowi_l3mdev = l3mdev_master_ifindex_rcu(dev);
282+
fl->flowi_flags |= FLOWI_FLAG_L3MDEV_OIF;
283+
}
282284

283285
/* oif set to L3mdev directs lookup to its table;
284286
* reset to avoid oif match in fib_lookup

0 commit comments

Comments
 (0)