Skip to content

Commit b5712e5

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 5159a2a commit b5712e5

File tree

8 files changed

+181
-66
lines changed

8 files changed

+181
-66
lines changed

include/netlink/route/nexthop.h

Lines changed: 13 additions & 0 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,28 @@ 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 int rtnl_nh_get_encap_mpls_ttl(struct rtnl_nh_encap *);
70+
5971
extern int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh,
6072
struct nl_addr *addr, uint8_t ttl);
6173
extern struct nl_addr *rtnl_route_nh_get_encap_mpls_dst(struct rtnl_nexthop *);
6274
extern uint8_t rtnl_route_nh_get_encap_mpls_ttl(struct rtnl_nexthop *);
75+
6376
#ifdef __cplusplus
6477
}
6578
#endif

include/nl-aux-route/nl-route.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "base/nl-base-utils.h"
77

88
#include <netlink/route/action.h>
9+
#include <netlink/route/nexthop.h>
910

1011
struct rtnl_link;
1112
void rtnl_link_put(struct rtnl_link *);
@@ -42,6 +43,10 @@ void rtnl_nh_put(struct rtnl_nh *);
4243
#define _nl_auto_rtnl_nh _nl_auto(_nl_auto_rtnl_nh_fcn)
4344
_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_nh *, _nl_auto_rtnl_nh_fcn, rtnl_nh_put);
4445

46+
#define _nl_auto_rtnl_nh_encap _nl_auto(_nl_auto_rtnl_nh_encap_fcn)
47+
_NL_AUTO_DEFINE_FCN_TYPED0(struct rtnl_nh_encap *, _nl_auto_rtnl_nh_encap_fcn,
48+
rtnl_nh_encap_free);
49+
4550
struct rtnl_link_af_ops;
4651
void rtnl_link_af_ops_put(struct rtnl_link_af_ops *);
4752
#define _nl_auto_rtnl_link_af_ops _nl_auto(_nl_auto_rtnl_link_af_ops_fcn)

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: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,7 @@ void rtnl_route_nh_free(struct rtnl_nexthop *nh)
9999
nl_addr_put(nh->rtnh_gateway);
100100
nl_addr_put(nh->rtnh_newdst);
101101
nl_addr_put(nh->rtnh_via);
102-
if (nh->rtnh_encap) {
103-
if (nh->rtnh_encap->ops && nh->rtnh_encap->ops->destructor)
104-
nh->rtnh_encap->ops->destructor(nh->rtnh_encap->priv);
105-
free(nh->rtnh_encap->priv);
106-
free(nh->rtnh_encap);
107-
}
102+
rtnl_nh_encap_free(nh->rtnh_encap);
108103
free(nh);
109104
}
110105

@@ -261,24 +256,6 @@ void rtnl_route_nh_dump(struct rtnl_nexthop *nh, struct nl_dump_params *dp)
261256
}
262257
}
263258

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

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

409407
/**

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: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77

88
#include <netlink/route/nexthop.h>
99

10-
#include "nl-route.h"
1110
#include "nexthop-encap.h"
11+
#include "nl-aux-core/nl-core.h"
12+
#include "nl-aux-route/nl-route.h"
13+
#include "nl-route.h"
1214

1315
struct mpls_iptunnel_encap {
1416
struct nl_addr *dst;
@@ -54,8 +56,9 @@ static struct nla_policy mpls_encap_policy[MPLS_IPTUNNEL_MAX + 1] = {
5456

5557
static int mpls_encap_parse_msg(struct nlattr *nla, struct rtnl_nexthop *nh)
5658
{
59+
_nl_auto_rtnl_nh_encap struct rtnl_nh_encap *nh_encap = NULL;
60+
_nl_auto_nl_addr struct nl_addr *labels = NULL;
5761
struct nlattr *tb[MPLS_IPTUNNEL_MAX + 1];
58-
struct nl_addr *labels;
5962
uint8_t ttl = 0;
6063
int err;
6164

@@ -73,11 +76,19 @@ static int mpls_encap_parse_msg(struct nlattr *nla, struct rtnl_nexthop *nh)
7376
if (tb[MPLS_IPTUNNEL_TTL])
7477
ttl = nla_get_u8(tb[MPLS_IPTUNNEL_TTL]);
7578

76-
err = rtnl_route_nh_encap_mpls(nh, labels, ttl);
79+
nh_encap = rtnl_nh_encap_alloc();
80+
if (!nh_encap)
81+
return -NLE_NOMEM;
7782

78-
nl_addr_put(labels);
83+
err = rtnl_nh_encap_mpls(nh_encap, labels, ttl);
84+
if (err < 0)
85+
return err;
7986

80-
return err;
87+
err = rtnl_route_nh_set_encap(nh, _nl_steal_pointer(&nh_encap));
88+
if (err < 0)
89+
return err;
90+
91+
return 0;
8192
}
8293

8394
static int mpls_encap_compare(void *_a, void *_b)
@@ -101,62 +112,86 @@ struct nh_encap_ops mpls_encap_ops = {
101112
.destructor = mpls_encap_destructor,
102113
};
103114

104-
int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh, struct nl_addr *addr,
105-
uint8_t ttl)
115+
int rtnl_nh_encap_mpls(struct rtnl_nh_encap *nh_encap, struct nl_addr *dst,
116+
uint8_t ttl)
106117
{
107118
struct mpls_iptunnel_encap *mpls_encap;
108-
struct rtnl_nh_encap *rtnh_encap;
109119

110-
if (!addr)
120+
if (!dst || !nh_encap)
111121
return -NLE_INVAL;
112122

113-
rtnh_encap = calloc(1, sizeof(*rtnh_encap));
114-
if (!rtnh_encap)
115-
return -NLE_NOMEM;
116-
117123
mpls_encap = calloc(1, sizeof(*mpls_encap));
118124
if (!mpls_encap) {
119-
free(rtnh_encap);
120125
return -NLE_NOMEM;
121126
}
122127

123-
mpls_encap->dst = nl_addr_get(addr);
128+
mpls_encap->dst = nl_addr_get(dst);
124129
mpls_encap->ttl = ttl;
125130

126-
rtnh_encap->priv = mpls_encap;
127-
rtnh_encap->ops = &mpls_encap_ops;
131+
nh_encap->priv = mpls_encap;
132+
nh_encap->ops = &mpls_encap_ops;
133+
134+
return 0;
135+
}
128136

129-
nh_set_encap(nh, rtnh_encap);
137+
int rtnl_route_nh_encap_mpls(struct rtnl_nexthop *nh, struct nl_addr *addr,
138+
uint8_t ttl)
139+
{
140+
_nl_auto_rtnl_nh_encap struct rtnl_nh_encap *rtnh_encap = NULL;
141+
int ret;
142+
143+
rtnh_encap = rtnl_nh_encap_alloc();
144+
if (!rtnh_encap)
145+
return -NLE_NOMEM;
146+
147+
ret = rtnl_nh_encap_mpls(rtnh_encap, addr, ttl);
148+
if (ret < 0)
149+
return ret;
150+
151+
rtnl_route_nh_set_encap(nh, _nl_steal_pointer(&rtnh_encap));
130152

131153
return 0;
132154
}
133155

134-
struct nl_addr *rtnl_route_nh_get_encap_mpls_dst(struct rtnl_nexthop *nh)
156+
struct nl_addr *rtnl_nh_get_encap_mpls_dst(struct rtnl_nh_encap *nh_encap)
135157
{
136158
struct mpls_iptunnel_encap *mpls_encap;
137159

138-
if (!nh->rtnh_encap ||
139-
nh->rtnh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
160+
if (!nh_encap || nh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
140161
return NULL;
141162

142-
mpls_encap = (struct mpls_iptunnel_encap *)nh->rtnh_encap->priv;
163+
mpls_encap = (struct mpls_iptunnel_encap *)nh_encap->priv;
143164
if (!mpls_encap)
144165
return NULL;
145166

146167
return mpls_encap->dst;
147168
}
148169

149-
uint8_t rtnl_route_nh_get_encap_mpls_ttl(struct rtnl_nexthop *nh)
170+
struct nl_addr *rtnl_route_nh_get_encap_mpls_dst(struct rtnl_nexthop *nh)
171+
{
172+
return rtnl_nh_get_encap_mpls_dst(nh->rtnh_encap);
173+
}
174+
175+
int rtnl_nh_get_encap_mpls_ttl(struct rtnl_nh_encap *nh_encap)
150176
{
151177
struct mpls_iptunnel_encap *mpls_encap;
152178

153-
if (!nh->rtnh_encap ||
154-
nh->rtnh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
155-
return 0;
179+
if (!nh_encap || !nh_encap->ops ||
180+
nh_encap->ops->encap_type != LWTUNNEL_ENCAP_MPLS)
181+
return -NLE_INVAL;
156182

157-
mpls_encap = (struct mpls_iptunnel_encap *)nh->rtnh_encap->priv;
183+
mpls_encap = (struct mpls_iptunnel_encap *)nh_encap->priv;
158184
if (!mpls_encap)
159-
return 0;
185+
return -NLE_INVAL;
160186

161187
return mpls_encap->ttl;
162188
}
189+
190+
uint8_t rtnl_route_nh_get_encap_mpls_ttl(struct rtnl_nexthop *nh)
191+
{
192+
int ttl = rtnl_nh_get_encap_mpls_ttl(nh->rtnh_encap);
193+
194+
if (ttl < 0)
195+
return 0;
196+
return (uint8_t)ttl;
197+
}

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)