Skip to content

Commit 3e08063

Browse files
KanjiMonsterthom311
authored andcommitted
route: expose nexthop id attribute
Routes may reference a nexthop (group) via the new nexthop API by its ID, so add accessors for setting and getting it. Referencing a nexthop is mutually exclusive to specifiying nexthops in the route, so make sure we do not do that when creating netlink messages (which may exist both, since netlink messages from the kernel contain both unless 'nexthop_compat_mode' is disabled). $ ip -6 r 2001:db8:3::/64 nhid 20 metric 1024 pref medium nexthop via 2001:db8:1::2 dev v0 weight 1 nexthop via 2001:db8:2::2 dev v1 weight 1 Before: $ nl-route-list inet6 2001:db8:3::/64 table main type unicast via 2001:db8:1::2 dev v0 via 2001:db8:2::2 dev v1 After: $ nl-route-list inet6 2001:db8:3::/64 table main type unicast nhid 20 via 2001:db8:1::2 dev v0 via 2001:db8:2::2 dev v1 Signed-off-by: Jonas Gorski <[email protected]> #386
1 parent 401c248 commit 3e08063

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

include/netlink/route/route.h

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ extern int rtnl_route_get_src_len(struct rtnl_route *);
9494
extern void rtnl_route_set_ttl_propagate(struct rtnl_route *route,
9595
uint8_t ttl_prop);
9696
extern int rtnl_route_get_ttl_propagate(struct rtnl_route *route);
97+
extern void rtnl_route_set_nhid(struct rtnl_route *, uint32_t);
98+
extern uint32_t rtnl_route_get_nhid(struct rtnl_route *);
9799

98100
extern void rtnl_route_add_nexthop(struct rtnl_route *,
99101
struct rtnl_nexthop *);

lib/route/route_obj.c

+34-1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct rtnl_route {
6363
uint32_t rt_metrics[RTAX_MAX];
6464
uint32_t rt_metrics_mask;
6565
uint32_t rt_nr_nh;
66+
uint32_t rt_nhid;
6667
struct nl_addr *rt_pref_src;
6768
struct nl_list_head rt_nexthops;
6869
struct rtnl_rtcacheinfo rt_cacheinfo;
@@ -88,6 +89,7 @@ struct rtnl_route {
8889
#define ROUTE_ATTR_REALMS 0x010000
8990
#define ROUTE_ATTR_CACHEINFO 0x020000
9091
#define ROUTE_ATTR_TTL_PROPAGATE 0x040000
92+
#define ROUTE_ATTR_NHID 0x080000
9193
/** @endcond */
9294

9395
static void route_constructor(struct nl_object *c)
@@ -192,6 +194,9 @@ static void route_dump_line(struct nl_object *a, struct nl_dump_params *p)
192194
if (r->ce_mask & ROUTE_ATTR_TOS && r->rt_tos != 0)
193195
nl_dump(p, "tos %#x ", r->rt_tos);
194196

197+
if (r->ce_mask & ROUTE_ATTR_NHID)
198+
nl_dump(p, "nhid %u ", r->rt_nhid);
199+
195200
if (r->ce_mask & ROUTE_ATTR_MULTIPATH) {
196201
struct rtnl_nexthop *nh;
197202

@@ -282,6 +287,9 @@ static void route_dump_details(struct nl_object *a, struct nl_dump_params *p)
282287
r->rt_ttl_propagate ? "enabled" : "disabled");
283288
}
284289

290+
if (r->ce_mask & ROUTE_ATTR_NHID)
291+
nl_dump(p, "nhid %u ", r->rt_nhid);
292+
285293
nl_dump(p, "\n");
286294

287295
if (r->ce_mask & ROUTE_ATTR_MULTIPATH) {
@@ -412,6 +420,7 @@ static uint64_t route_compare(struct nl_object *_a, struct nl_object *_b,
412420
nl_addr_cmp(a->rt_pref_src, b->rt_pref_src));
413421
diff |= _DIFF(ROUTE_ATTR_TTL_PROPAGATE,
414422
a->rt_ttl_propagate != b->rt_ttl_propagate);
423+
diff |= _DIFF(ROUTE_ATTR_NHID, a->rt_nhid != b->rt_nhid);
415424

416425
if (flags & LOOSE_COMPARISON) {
417426
nl_list_for_each_entry(nh_b, &b->rt_nexthops, rtnh_list) {
@@ -617,6 +626,7 @@ static const struct trans_tbl route_attrs[] = {
617626
__ADD(ROUTE_ATTR_REALMS, realms),
618627
__ADD(ROUTE_ATTR_CACHEINFO, cacheinfo),
619628
__ADD(ROUTE_ATTR_TTL_PROPAGATE, ttl_propagate),
629+
__ADD(ROUTE_ATTR_NHID, nhid),
620630
};
621631

622632
static char *route_attrs2str(int attrs, char *buf, size_t len)
@@ -964,6 +974,21 @@ int rtnl_route_get_ttl_propagate(struct rtnl_route *route)
964974
return route->rt_ttl_propagate;
965975
}
966976

977+
void rtnl_route_set_nhid(struct rtnl_route *route, uint32_t nhid)
978+
{
979+
route->rt_nhid = nhid;
980+
981+
if (nhid > 0)
982+
route->ce_mask |= ROUTE_ATTR_NHID;
983+
else
984+
route->ce_mask &= ~ROUTE_ATTR_NHID;
985+
}
986+
987+
uint32_t rtnl_route_get_nhid(struct rtnl_route *route)
988+
{
989+
return route->rt_nhid;
990+
}
991+
967992
/** @} */
968993

969994
/**
@@ -1046,6 +1071,7 @@ static struct nla_policy route_policy[RTA_MAX+1] = {
10461071
[RTA_TTL_PROPAGATE] = { .type = NLA_U8 },
10471072
[RTA_ENCAP] = { .type = NLA_NESTED },
10481073
[RTA_ENCAP_TYPE] = { .type = NLA_U16 },
1074+
[RTA_NH_ID] = { .type = NLA_U32 },
10491075
};
10501076

10511077
static int parse_multipath(struct rtnl_route *route, struct nlattr *attr)
@@ -1337,6 +1363,10 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
13371363
return err;
13381364
}
13391365

1366+
if (tb[RTA_NH_ID]) {
1367+
rtnl_route_set_nhid(route, nla_get_u32(tb[RTA_NH_ID]));
1368+
}
1369+
13401370
if (old_nh) {
13411371
rtnl_route_nh_set_flags(old_nh, rtm->rtm_flags & 0xff);
13421372
if (route->rt_nr_nh == 0) {
@@ -1439,7 +1469,10 @@ int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route)
14391469
nla_nest_end(msg, metrics);
14401470
}
14411471

1442-
if (rtnl_route_get_nnexthops(route) == 1) {
1472+
/* Nexthop specification and nexthop id are mutually exclusive */
1473+
if (route->ce_mask & ROUTE_ATTR_NHID) {
1474+
NLA_PUT_U32(msg, RTA_NH_ID, route->rt_nhid);
1475+
} else if (rtnl_route_get_nnexthops(route) == 1) {
14431476
struct rtnl_nexthop *nh;
14441477

14451478
nh = rtnl_route_nexthop_n(route, 0);

libnl-route-3.sym

+2
Original file line numberDiff line numberDiff line change
@@ -1328,5 +1328,7 @@ global:
13281328
rtnl_link_bridge_set_port_vlan_map_range;
13291329
rtnl_link_bridge_set_port_vlan_pvid;
13301330
rtnl_link_bridge_unset_port_vlan_map_range;
1331+
rtnl_route_get_nhid;
13311332
rtnl_route_nh_identical;
1333+
rtnl_route_set_nhid;
13321334
} libnl_3_9;

0 commit comments

Comments
 (0)