Skip to content

Commit dcb1ecb

Browse files
dsaherndavem330
authored andcommitted
ipv4: Prepare for fib6_nh from a nexthop object
Convert more IPv4 code to use fib_nh_common over fib_nh to enable routes to use a fib6_nh based nexthop. In the end, only code not using a nexthop object in a fib_info should directly access fib_nh in a fib_info without checking the famiy and going through fib_nh_common. Those functions will be marked when it is not directly evident. Signed-off-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5481d73 commit dcb1ecb

File tree

7 files changed

+69
-37
lines changed

7 files changed

+69
-37
lines changed

include/net/ip_fib.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ struct fib_result_nl {
195195
#define FIB_TABLE_HASHSZ 2
196196
#endif
197197

198-
__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh,
199-
unsigned char scope);
198+
__be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc,
199+
unsigned char scope);
200200
__be32 fib_result_prefsrc(struct net *net, struct fib_result *res);
201201

202202
#define FIB_RES_NHC(res) ((res).nhc)
@@ -455,11 +455,18 @@ static inline void fib_combine_itag(u32 *itag, const struct fib_result *res)
455455
{
456456
#ifdef CONFIG_IP_ROUTE_CLASSID
457457
struct fib_nh_common *nhc = res->nhc;
458-
struct fib_nh *nh = container_of(nhc, struct fib_nh, nh_common);
459458
#ifdef CONFIG_IP_MULTIPLE_TABLES
460459
u32 rtag;
461460
#endif
462-
*itag = nh->nh_tclassid << 16;
461+
if (nhc->nhc_family == AF_INET) {
462+
struct fib_nh *nh;
463+
464+
nh = container_of(nhc, struct fib_nh, nh_common);
465+
*itag = nh->nh_tclassid << 16;
466+
} else {
467+
*itag = 0;
468+
}
469+
463470
#ifdef CONFIG_IP_MULTIPLE_TABLES
464471
rtag = res->tclassid;
465472
if (*itag == 0)

net/ipv4/fib_frontend.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,9 @@ static inline unsigned int __inet_dev_addr_type(struct net *net,
235235
if (table) {
236236
ret = RTN_UNICAST;
237237
if (!fib_table_lookup(table, &fl4, &res, FIB_LOOKUP_NOREF)) {
238-
struct fib_nh *nh = fib_info_nh(res.fi, 0);
238+
struct fib_nh_common *nhc = fib_info_nhc(res.fi, 0);
239239

240-
if (!dev || dev == nh->fib_nh_dev)
240+
if (!dev || dev == nhc->nhc_dev)
241241
ret = res.type;
242242
}
243243
}
@@ -325,18 +325,18 @@ bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev)
325325
int ret;
326326

327327
for (ret = 0; ret < fib_info_num_path(fi); ret++) {
328-
const struct fib_nh *nh = fib_info_nh(fi, ret);
328+
const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
329329

330-
if (nh->fib_nh_dev == dev) {
330+
if (nhc->nhc_dev == dev) {
331331
dev_match = true;
332332
break;
333-
} else if (l3mdev_master_ifindex_rcu(nh->fib_nh_dev) == dev->ifindex) {
333+
} else if (l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) {
334334
dev_match = true;
335335
break;
336336
}
337337
}
338338
#else
339-
if (fib_info_nh(fi, 0)->fib_nh_dev == dev)
339+
if (fib_info_nhc(fi, 0)->nhc_dev == dev)
340340
dev_match = true;
341341
#endif
342342

net/ipv4/fib_rules.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg
147147
struct net_device *dev = NULL;
148148

149149
if (result->fi) {
150-
struct fib_nh *nh = fib_info_nh(result->fi, 0);
150+
struct fib_nh_common *nhc = fib_info_nhc(result->fi, 0);
151151

152-
dev = nh->fib_nh_dev;
152+
dev = nhc->nhc_dev;
153153
}
154154

155155
/* do not accept result if the route does

net/ipv4/fib_semantics.c

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ static unsigned int fib_info_cnt;
6161
#define DEVINDEX_HASHSIZE (1U << DEVINDEX_HASHBITS)
6262
static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE];
6363

64+
/* for_nexthops and change_nexthops only used when nexthop object
65+
* is not set in a fib_info. The logic within can reference fib_nh.
66+
*/
6467
#ifdef CONFIG_IP_ROUTE_MULTIPATH
6568

6669
#define for_nexthops(fi) { \
@@ -402,20 +405,23 @@ static inline size_t fib_nlmsg_size(struct fib_info *fi)
402405

403406
/* each nexthop is packed in an attribute */
404407
size_t nhsize = nla_total_size(sizeof(struct rtnexthop));
408+
unsigned int i;
405409

406410
/* may contain flow and gateway attribute */
407411
nhsize += 2 * nla_total_size(4);
408412

409413
/* grab encap info */
410-
for_nexthops(fi) {
411-
if (nh->fib_nh_lws) {
414+
for (i = 0; i < fib_info_num_path(fi); i++) {
415+
struct fib_nh_common *nhc = fib_info_nhc(fi, i);
416+
417+
if (nhc->nhc_lwtstate) {
412418
/* RTA_ENCAP_TYPE */
413419
nh_encapsize += lwtunnel_get_encap_size(
414-
nh->fib_nh_lws);
420+
nhc->nhc_lwtstate);
415421
/* RTA_ENCAP */
416422
nh_encapsize += nla_total_size(2);
417423
}
418-
} endfor_nexthops(fi);
424+
}
419425

420426
/* all nexthops are packed in a nested attribute */
421427
payload += nla_total_size((nhs * nhsize) + nh_encapsize);
@@ -1194,9 +1200,15 @@ static void fib_info_hash_move(struct hlist_head *new_info_hash,
11941200
fib_info_hash_free(old_laddrhash, bytes);
11951201
}
11961202

1197-
__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh,
1198-
unsigned char scope)
1203+
__be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc,
1204+
unsigned char scope)
11991205
{
1206+
struct fib_nh *nh;
1207+
1208+
if (nhc->nhc_family != AF_INET)
1209+
return inet_select_addr(nhc->nhc_dev, 0, scope);
1210+
1211+
nh = container_of(nhc, struct fib_nh, nh_common);
12001212
nh->nh_saddr = inet_select_addr(nh->fib_nh_dev, nh->fib_nh_gw4, scope);
12011213
nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid);
12021214

@@ -1206,16 +1218,19 @@ __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh,
12061218
__be32 fib_result_prefsrc(struct net *net, struct fib_result *res)
12071219
{
12081220
struct fib_nh_common *nhc = res->nhc;
1209-
struct fib_nh *nh;
12101221

12111222
if (res->fi->fib_prefsrc)
12121223
return res->fi->fib_prefsrc;
12131224

1214-
nh = container_of(nhc, struct fib_nh, nh_common);
1215-
if (nh->nh_saddr_genid == atomic_read(&net->ipv4.dev_addr_genid))
1216-
return nh->nh_saddr;
1225+
if (nhc->nhc_family == AF_INET) {
1226+
struct fib_nh *nh;
1227+
1228+
nh = container_of(nhc, struct fib_nh, nh_common);
1229+
if (nh->nh_saddr_genid == atomic_read(&net->ipv4.dev_addr_genid))
1230+
return nh->nh_saddr;
1231+
}
12171232

1218-
return fib_info_update_nh_saddr(net, nh, res->fi->fib_scope);
1233+
return fib_info_update_nhc_saddr(net, nhc, res->fi->fib_scope);
12191234
}
12201235

12211236
static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc)
@@ -1397,7 +1412,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
13971412
}
13981413

13991414
change_nexthops(fi) {
1400-
fib_info_update_nh_saddr(net, nexthop_nh, fi->fib_scope);
1415+
fib_info_update_nhc_saddr(net, &nexthop_nh->nh_common,
1416+
fi->fib_scope);
14011417
if (nexthop_nh->fib_nh_gw_family == AF_INET6)
14021418
fi->fib_nh_is_v6 = true;
14031419
} endfor_nexthops(fi)
@@ -1625,17 +1641,22 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
16251641
nla_put_in_addr(skb, RTA_PREFSRC, fi->fib_prefsrc))
16261642
goto nla_put_failure;
16271643
if (nhs == 1) {
1628-
const struct fib_nh *nh = fib_info_nh(fi, 0);
1644+
const struct fib_nh_common *nhc = fib_info_nhc(fi, 0);
16291645
unsigned char flags = 0;
16301646

1631-
if (fib_nexthop_info(skb, &nh->nh_common, &flags, false) < 0)
1647+
if (fib_nexthop_info(skb, nhc, &flags, false) < 0)
16321648
goto nla_put_failure;
16331649

16341650
rtm->rtm_flags = flags;
16351651
#ifdef CONFIG_IP_ROUTE_CLASSID
1636-
if (nh->nh_tclassid &&
1637-
nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid))
1638-
goto nla_put_failure;
1652+
if (nhc->nhc_family == AF_INET) {
1653+
struct fib_nh *nh;
1654+
1655+
nh = container_of(nhc, struct fib_nh, nh_common);
1656+
if (nh->nh_tclassid &&
1657+
nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid))
1658+
goto nla_put_failure;
1659+
}
16391660
#endif
16401661
} else {
16411662
if (fib_add_multipath(skb, fi) < 0)

net/ipv4/fib_trie.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,9 +2724,9 @@ static unsigned int fib_flag_trans(int type, __be32 mask, struct fib_info *fi)
27242724
if (type == RTN_UNREACHABLE || type == RTN_PROHIBIT)
27252725
flags = RTF_REJECT;
27262726
if (fi) {
2727-
const struct fib_nh *nh = fib_info_nh(fi, 0);
2727+
const struct fib_nh_common *nhc = fib_info_nhc(fi, 0);
27282728

2729-
if (nh->fib_nh_gw4)
2729+
if (nhc->nhc_gw.ipv4)
27302730
flags |= RTF_GATEWAY;
27312731
}
27322732
if (mask == htonl(0xFFFFFFFF))
@@ -2773,14 +2773,17 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
27732773
seq_setwidth(seq, 127);
27742774

27752775
if (fi) {
2776-
struct fib_nh *nh = fib_info_nh(fi, 0);
2776+
struct fib_nh_common *nhc = fib_info_nhc(fi, 0);
2777+
__be32 gw = 0;
2778+
2779+
if (nhc->nhc_gw_family == AF_INET)
2780+
gw = nhc->nhc_gw.ipv4;
27772781

27782782
seq_printf(seq,
27792783
"%s\t%08X\t%08X\t%04X\t%d\t%u\t"
27802784
"%d\t%08X\t%d\t%u\t%u",
2781-
nh->fib_nh_dev ? nh->fib_nh_dev->name : "*",
2782-
prefix,
2783-
nh->fib_nh_gw4, flags, 0, 0,
2785+
nhc->nhc_dev ? nhc->nhc_dev->name : "*",
2786+
prefix, gw, flags, 0, 0,
27842787
fi->fib_priority,
27852788
mask,
27862789
(fi->fib_advmss ?

net/ipv4/nexthop.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,8 @@ static int nh_create_ipv4(struct net *net, struct nexthop *nh,
815815
err = fib_check_nh(net, fib_nh, tb_id, 0, extack);
816816
if (!err) {
817817
nh->nh_flags = fib_nh->fib_nh_flags;
818-
fib_info_update_nh_saddr(net, fib_nh, fib_nh->fib_nh_scope);
818+
fib_info_update_nhc_saddr(net, &fib_nh->nh_common,
819+
fib_nh->fib_nh_scope);
819820
} else {
820821
fib_nh_release(net, fib_nh);
821822
}

net/ipv4/route.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1585,7 +1585,7 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
15851585
ip_dst_init_metrics(&rt->dst, fi->fib_metrics);
15861586

15871587
#ifdef CONFIG_IP_ROUTE_CLASSID
1588-
{
1588+
if (nhc->nhc_family == AF_INET) {
15891589
struct fib_nh *nh;
15901590

15911591
nh = container_of(nhc, struct fib_nh, nh_common);

0 commit comments

Comments
 (0)