summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-06-23 17:32:05 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-06-23 17:36:34 +0300
commit2fd4bfe330d0f1a3f6aa8cab7b54809b257af4e8 (patch)
tree9caef95e991c1bcd3f84ca93d623a11876c1d020
parent4deb615d7bd7134dd15686b9ea4239f73e20009e (diff)
downloadaccel-ppp-2fd4bfe330d0f1a3f6aa8cab7b54809b257af4e8.tar.gz
accel-ppp-2fd4bfe330d0f1a3f6aa8cab7b54809b257af4e8.zip
iputils: balance rtnetlink handles in VRF lookup
-rw-r--r--accel-pppd/libnetlink/iputils.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/accel-pppd/libnetlink/iputils.c b/accel-pppd/libnetlink/iputils.c
index 34181e2a..a5e3bc51 100644
--- a/accel-pppd/libnetlink/iputils.c
+++ b/accel-pppd/libnetlink/iputils.c
@@ -469,20 +469,24 @@ static int ipvrf_get_table(uint32_t *tb_id, const char *vrf_name)
struct ifinfomsg i;
char buf[4096];
} req;
- struct rtnl_handle *rth = net->rtnl_get();
struct rtattr *tb[IFLA_MAX+1];
struct rtattr *li[IFLA_INFO_MAX+1];
struct rtattr *vrf_attr[IFLA_VRF_MAX + 1];
struct ifinfomsg *ifi;
+ struct rtnl_handle *rth;
int len;
int r = -1;
*tb_id = RT_TABLE_MAIN;
- log_ppp_info2("utils: getting route table for %s\n", vrf_name);
-
if (!vrf_name)
return 0;
+ log_ppp_info2("utils: getting route table for %s\n", vrf_name);
+
+ rth = net->rtnl_get();
+ if (!rth)
+ return -1;
+
memset(&req, 0, sizeof(req) - 4096);
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
@@ -495,7 +499,7 @@ static int ipvrf_get_table(uint32_t *tb_id, const char *vrf_name)
r = rtnl_talk(rth, &req.n, 0, 0, &req.n, NULL, NULL, 0);
if (r < 0) {
log_ppp_error("BUG: route table \"%s\" not found\n", vrf_name);
- return r;
+ goto out;
}
ifi = NLMSG_DATA(&req.n);
@@ -529,9 +533,13 @@ static int ipvrf_get_table(uint32_t *tb_id, const char *vrf_name)
if (*tb_id == 0)
log_ppp_error("BUG: VRF %s is missing table id\n", vrf_name);
- return 0;
+ r = 0;
+ goto out;
error:
- return -1;
+ r = -1;
+out:
+ net->rtnl_put(rth);
+ return r;
}
#endif
@@ -552,8 +560,10 @@ int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
uint32_t rt_table = RT_TABLE_MAIN;
#ifdef HAVE_VRF
- if (ipvrf_get_table(&rt_table, vrf_name) < 0)
- return -1;
+ if (ipvrf_get_table(&rt_table, vrf_name) < 0) {
+ r = -1;
+ goto out;
+ }
#endif
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
@@ -581,6 +591,7 @@ int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0)
r = -1;
+out:
net->rtnl_put(rth);
return r;
@@ -603,8 +614,10 @@ int __export iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
uint32_t rt_table = RT_TABLE_MAIN;
#ifdef HAVE_VRF
- if (ipvrf_get_table(&rt_table, vrf_name) < 0)
- return -1;
+ if (ipvrf_get_table(&rt_table, vrf_name) < 0) {
+ r = -1;
+ goto out;
+ }
#endif
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
@@ -632,6 +645,7 @@ int __export iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0)
r = -1;
+out:
net->rtnl_put(rth);
return r;
@@ -654,8 +668,10 @@ int __export ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len,
uint32_t rt_table = RT_TABLE_MAIN;
#ifdef HAVE_VRF
- if (ipvrf_get_table(&rt_table, vrf_name) < 0)
- return -1;
+ if (ipvrf_get_table(&rt_table, vrf_name) < 0) {
+ r = -1;
+ goto out;
+ }
#endif
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
@@ -681,6 +697,7 @@ int __export ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len,
if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0)
r = -1;
+out:
net->rtnl_put(rth);
return r;
@@ -703,8 +720,10 @@ int __export ip6route_del(int ifindex, const struct in6_addr *dst, int pref_len,
uint32_t rt_table = RT_TABLE_MAIN;
#ifdef HAVE_VRF
- if (ipvrf_get_table(&rt_table, vrf_name) < 0)
- return -1;
+ if (ipvrf_get_table(&rt_table, vrf_name) < 0) {
+ r = -1;
+ goto out;
+ }
#endif
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
@@ -730,6 +749,7 @@ int __export ip6route_del(int ifindex, const struct in6_addr *dst, int pref_len,
if (rtnl_talk(rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0)
r = -1;
+out:
net->rtnl_put(rth);
return r;