Skip to content

Commit f1263ca

Browse files
committed
[nh-encap] Extract functions to directly manipulate struct rtnl_nh_encap
The goal is to have struct rtnl_nh_encap be used for the route's nexthop (In struct rtnl_nexthop) but also directly in an IP nexthop (struct rtnl_nh). So, let's extract some functions to manipulate struct rtnl_nh_encap directly. Ideally, even for the route's nexthop we will use those to manipulate the encap. Ideally we stop using rtnl_route_nh_encap_mpls (and friends) and rather configure an encapsulation on a route's nexthop by using: nh = rtnl_nh_encap_alloc() rtnl_nh_encap_mpls(nh, ...) rtnl_route_nh_set_encap(rtnh, nh) Add tests for these new functions and drop the tests for the deprecated ones. Signed-off-by: Christoph Paasch <[email protected]>
1 parent a6a808b commit f1263ca

File tree

7 files changed

+186
-63
lines changed

7 files changed

+186
-63
lines changed

include/netlink/route/nexthop.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern "C" {
1414
#endif
1515

1616
struct rtnl_nexthop;
17+
struct rtnl_nh_encap;
1718

1819
enum {
1920
NH_DUMP_FROM_ONELINE = -2,
@@ -50,16 +51,32 @@ extern int rtnl_route_nh_set_newdst(struct rtnl_nexthop *, struct nl_addr *);
5051
extern struct nl_addr *rtnl_route_nh_get_newdst(struct rtnl_nexthop *);
5152
extern int rtnl_route_nh_set_via(struct rtnl_nexthop *, struct nl_addr *);
5253
extern struct nl_addr *rtnl_route_nh_get_via(struct rtnl_nexthop *);
54+
extern int rtnl_route_nh_set_encap(struct rtnl_nexthop *,
55+
struct rtnl_nh_encap *);
56+
extern struct rtnl_nh_encap *rtnl_route_nh_get_encap(struct rtnl_nexthop *);
5357
extern char *rtnl_route_nh_flags2str(int, char *, size_t);
5458
extern int rtnl_route_nh_str2flags(const char *);
5559

5660
/*
5761
* nexthop encapsulations
5862
*/
63+
extern struct rtnl_nh_encap *rtnl_nh_encap_alloc(void);
64+
extern void rtnl_nh_encap_free(struct rtnl_nh_encap *nh_encap);
65+
66+
extern int rtnl_nh_encap_mpls(struct rtnl_nh_encap *nh_encap,
67+
struct nl_addr *dst, uint8_t ttl);
68+
struct nl_addr *rtnl_nh_get_encap_mpls_dst(struct rtnl_nh_encap *);
69+
extern uint8_t rtnl_nh_get_encap_mpls_ttl(struct rtnl_nh_encap *);
70+
71+
/* Deprecated */
5972
extern int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh,
60-
struct nl_addr *addr, uint8_t ttl);
61-
extern struct nl_addr *rtnl_route_nh_get_encap_mpls_dst(struct rtnl_nexthop *);
62-
extern uint8_t rtnl_route_nh_get_encap_mpls_ttl(struct rtnl_nexthop *);
73+
struct nl_addr *addr, uint8_t ttl)
74+
__attribute__((deprecated));
75+
extern struct nl_addr *rtnl_route_nh_get_encap_mpls_dst(struct rtnl_nexthop *)
76+
__attribute__((deprecated));
77+
extern uint8_t rtnl_route_nh_get_encap_mpls_ttl(struct rtnl_nexthop *)
78+
__attribute__((deprecated));
79+
6380
#ifdef __cplusplus
6481
}
6582
#endif

lib/route/nexthop-encap.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ struct rtnl_nh_encap;
1818
/*
1919
* generic nexthop encap
2020
*/
21-
void nh_set_encap(struct rtnl_nexthop *nh, struct rtnl_nh_encap *rtnh_encap);
22-
2321
int nh_encap_parse_msg(struct nlattr *encap, struct nlattr *encap_type,
2422
struct rtnl_nexthop *rtnh);
2523
int nh_encap_build_msg(struct nl_msg *msg, struct rtnl_nh_encap *rtnh_encap);

lib/route/nexthop.c

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,7 @@ void rtnl_route_nh_free(struct rtnl_nexthop *nh)
9898
nl_addr_put(nh->rtnh_gateway);
9999
nl_addr_put(nh->rtnh_newdst);
100100
nl_addr_put(nh->rtnh_via);
101-
if (nh->rtnh_encap) {
102-
if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
103-
nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
104-
free(nh->rtnh_encap->priv);
105-
free(nh->rtnh_encap);
106-
}
101+
rtnl_nh_encap_free(nh->rtnh_encap);
107102
free(nh);
108103
}
109104

@@ -260,24 +255,6 @@ void rtnl_route_nh_dump(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
260255
}
261256
}
262257

263-
void nh_set_encap(struct rtnl_nexthop *nh, struct rtnl_nh_encap *rtnh_encap)
264-
{
265-
if (nh->rtnh_encap) {
266-
if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
267-
nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
268-
free(nh->rtnh_encap->priv);
269-
free(nh->rtnh_encap);
270-
}
271-
272-
if (rtnh_encap) {
273-
nh->rtnh_encap = rtnh_encap;
274-
nh->ce_mask |= NH_ATTR_ENCAP;
275-
} else {
276-
nh->rtnh_encap = NULL;
277-
nh->ce_mask &= ~NH_ATTR_ENCAP;
278-
}
279-
}
280-
281258
/**
282259
* @name Attributes
283260
* @{
@@ -403,6 +380,30 @@ struct nl_addr *rtnl_route_nh_get_via(struct rtnl_nexthop *nh)
403380
return nh->rtnh_via;
404381
}
405382

383+
int rtnl_route_nh_set_encap(struct rtnl_nexthop *nh,
384+
struct rtnl_nh_encap *nh_encap)
385+
{
386+
if (!nh)
387+
return -NLE_INVAL;
388+
389+
if (nh->rtnh_encap) {
390+
if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
391+
nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
392+
free(nh->rtnh_encap->priv);
393+
free(nh->rtnh_encap);
394+
}
395+
396+
if (nh_encap) {
397+
nh->rtnh_encap = nh_encap;
398+
nh->ce_mask |= NH_ATTR_ENCAP;
399+
} else {
400+
nh->rtnh_encap = NULL;
401+
nh->ce_mask &= ~NH_ATTR_ENCAP;
402+
}
403+
404+
return 0;
405+
}
406+
406407
/** @} */
407408

408409
/**

lib/route/nh.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "nl-aux-route/nl-route.h"
1515
#include "nl-route.h"
16+
#include "nexthop-encap.h"
1617
#include "nl-priv-dynamic-core/nl-core.h"
1718
#include "nl-priv-dynamic-core/cache-api.h"
1819

@@ -651,6 +652,33 @@ int rtnl_nh_add(struct nl_sock *sk, struct rtnl_nh *nh, int flags)
651652
return wait_for_ack(sk);
652653
}
653654

655+
struct rtnl_nh_encap *rtnl_nh_encap_alloc(void)
656+
{
657+
return calloc(1, sizeof(struct rtnl_nh_encap));
658+
}
659+
660+
void rtnl_nh_encap_free(struct rtnl_nh_encap *nh_encap)
661+
{
662+
if (!nh_encap)
663+
return;
664+
665+
if (nh_encap->ops && nh_encap->ops->destructor)
666+
nh_encap->ops->destructor(nh_encap->priv);
667+
668+
free(nh_encap->priv);
669+
free(nh_encap);
670+
}
671+
672+
/*
673+
* Retrieve the encapsulation associated with a nexthop if any.
674+
*/
675+
struct rtnl_nh_encap *rtnl_route_nh_get_encap(struct rtnl_nexthop *nh)
676+
{
677+
if (!nh)
678+
return NULL;
679+
680+
return nh->rtnh_encap;
681+
}
654682
static struct nla_policy nh_res_group_policy[NHA_RES_GROUP_MAX + 1] = {
655683
[NHA_RES_GROUP_UNSPEC] = { .type = NLA_UNSPEC },
656684
[NHA_RES_GROUP_BUCKETS] = { .type = NLA_U16 },

lib/route/nh_encap_mpls.c

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static struct nla_policy mpls_encap_policy[MPLS_IPTUNNEL_MAX + 1] = {
5555
static int mpls_encap_parse_msg(struct nlattr *nla, struct rtnl_nexthop *nh)
5656
{
5757
struct nlattr *tb[MPLS_IPTUNNEL_MAX + 1];
58+
struct rtnl_nh_encap *nh_encap;
5859
struct nl_addr *labels;
5960
uint8_t ttl = 0;
6061
int err;
@@ -73,10 +74,30 @@ static int mpls_encap_parse_msg(struct nlattr *nla, struct rtnl_nexthop *nh)
7374
if (tb[MPLS_IPTUNNEL_TTL])
7475
ttl = nla_get_u8(tb[MPLS_IPTUNNEL_TTL]);
7576

76-
err = rtnl_route_nh_encap_mpls(nh, labels, ttl);
77+
nh_encap = rtnl_nh_encap_alloc();
78+
if (!nh_encap) {
79+
err = -NLE_NOMEM;
80+
goto err_out;
81+
}
82+
83+
err = rtnl_nh_encap_mpls(nh_encap, labels, ttl);
84+
if (err < 0) {
85+
goto err_out;
86+
}
87+
88+
err = rtnl_route_nh_set_encap(nh, nh_encap);
89+
if (err < 0) {
90+
goto err_out;
91+
}
7792

7893
nl_addr_put(labels);
7994

95+
return 0;
96+
97+
err_out:
98+
rtnl_nh_encap_free(nh_encap);
99+
nl_addr_put(labels);
100+
80101
return err;
81102
}
82103

@@ -101,62 +122,84 @@ struct nh_encap_ops mpls_encap_ops = {
101122
.destructor = mpls_encap_destructor,
102123
};
103124

104-
int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh, struct nl_addr *addr,
105-
uint8_t ttl)
125+
int rtnl_nh_encap_mpls(struct rtnl_nh_encap *nh_encap, struct nl_addr *dst,
126+
uint8_t ttl)
106127
{
107128
struct mpls_iptunnel_encap *mpls_encap;
108-
struct rtnl_nh_encap *rtnh_encap;
109129

110-
if (!addr)
130+
if (!dst || !nh_encap)
111131
return -NLE_INVAL;
112132

113-
rtnh_encap = calloc(1, sizeof(*rtnh_encap));
114-
if (!rtnh_encap)
115-
return -NLE_NOMEM;
116-
117133
mpls_encap = calloc(1, sizeof(*mpls_encap));
118134
if (!mpls_encap) {
119-
free(rtnh_encap);
120135
return -NLE_NOMEM;
121136
}
122137

123-
mpls_encap->dst = nl_addr_get(addr);
138+
mpls_encap->dst = nl_addr_get(dst);
124139
mpls_encap->ttl = ttl;
125140

126-
rtnh_encap->priv = mpls_encap;
127-
rtnh_encap->ops = &mpls_encap_ops;
141+
nh_encap->priv = mpls_encap;
142+
nh_encap->ops = &mpls_encap_ops;
128143

129-
nh_set_encap(nh, rtnh_encap);
144+
return 0;
145+
}
146+
147+
int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh, struct nl_addr *addr,
148+
uint8_t ttl)
149+
{
150+
struct rtnl_nh_encap *rtnh_encap;
151+
int ret;
152+
153+
rtnh_encap = rtnl_nh_encap_alloc();
154+
if (!rtnh_encap) {
155+
return -NLE_NOMEM;
156+
}
157+
158+
ret = rtnl_nh_encap_mpls(rtnh_encap, addr, ttl);
159+
if (ret < 0) {
160+
rtnl_nh_encap_free(rtnh_encap);
161+
return ret;
162+
}
163+
164+
rtnl_route_nh_set_encap(nh, rtnh_encap);
130165

131166
return 0;
132167
}
133168

134-
struct nl_addr *rtnl_route_nh_get_encap_mpls_dst(struct rtnl_nexthop *nh)
169+
struct nl_addr *rtnl_nh_get_encap_mpls_dst(struct rtnl_nh_encap *nh_encap)
135170
{
136171
struct mpls_iptunnel_encap *mpls_encap;
137172

138-
if (!nh->rtnh_encap ||
139-
nh->rtnh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
173+
if (!nh_encap || nh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
140174
return NULL;
141175

142-
mpls_encap = (struct mpls_iptunnel_encap *)nh->rtnh_encap->priv;
176+
mpls_encap = (struct mpls_iptunnel_encap *)nh_encap->priv;
143177
if (!mpls_encap)
144178
return NULL;
145179

146180
return mpls_encap->dst;
147181
}
148182

149-
uint8_t rtnl_route_nh_get_encap_mpls_ttl(struct rtnl_nexthop *nh)
183+
struct nl_addr *rtnl_route_nh_get_encap_mpls_dst(struct rtnl_nexthop *nh)
184+
{
185+
return rtnl_nh_get_encap_mpls_dst(nh->rtnh_encap);
186+
}
187+
188+
uint8_t rtnl_nh_get_encap_mpls_ttl(struct rtnl_nh_encap *nh_encap)
150189
{
151190
struct mpls_iptunnel_encap *mpls_encap;
152191

153-
if (!nh->rtnh_encap ||
154-
nh->rtnh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
192+
if (!nh_encap || nh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
155193
return 0;
156194

157-
mpls_encap = (struct mpls_iptunnel_encap *)nh->rtnh_encap->priv;
195+
mpls_encap = (struct mpls_iptunnel_encap *)nh_encap->priv;
158196
if (!mpls_encap)
159197
return 0;
160198

161199
return mpls_encap->ttl;
162200
}
201+
202+
uint8_t rtnl_route_nh_get_encap_mpls_ttl(struct rtnl_nexthop *nh)
203+
{
204+
return rtnl_nh_get_encap_mpls_ttl(nh->rtnh_encap);
205+
}

libnl-route-3.sym

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,11 @@ global:
13711371
rtnl_link_ip6_tnl_set_collect_metadata;
13721372
rtnl_link_is_bond;
13731373
rtnl_nh_add;
1374+
rtnl_nh_encap_alloc;
1375+
rtnl_nh_encap_free;
1376+
rtnl_nh_encap_mpls;
1377+
rtnl_nh_get_encap_mpls_dst;
1378+
rtnl_nh_get_encap_mpls_ttl;
13741379
rtnl_nh_get_family;
13751380
rtnl_nh_get_group_type;
13761381
rtnl_nh_get_oif;
@@ -1385,4 +1390,6 @@ global:
13851390
rtnl_nh_set_res_group_bucket_size;
13861391
rtnl_nh_set_res_group_idle_timer;
13871392
rtnl_nh_set_res_group_unbalanced_timer;
1393+
rtnl_route_nh_set_encap;
1394+
rtnl_route_nh_get_encap;
13881395
} libnl_3_11;

0 commit comments

Comments
 (0)