Compare commits

...

12 Commits

Author SHA1 Message Date
Daniil Baturin
054d4f9d43
Merge pull request #927 from sever-sever/T4409
T4409: Fix Framed-Route with attr Accel-VRF-Name
2025-06-10 15:56:23 +01:00
Daniil Baturin
4726ad65ae
Merge pull request #972 from Gabin-CC/current
build: T7453: Make raw image building logic more robust
2025-06-10 15:46:58 +01:00
Christian Breunig
9182e62abc
Merge pull request #973 from tjjh89017/T7534
T7534: netfilter: add asciidoc-base as build depend
2025-06-10 16:43:55 +02:00
Daniil Baturin
75f72ab901
Remove a stray debug output 2025-06-10 15:43:29 +01:00
Daniil Baturin
7d40712037
Merge pull request #975 from sever-sever/T7530
T7530: Build package binaries script should exit if repo is absent
2025-06-10 15:36:23 +01:00
Date Huang
e862f1c13b T7534: netfilter: add asciidoc-base,bison as build depend
Signed-off-by: Date Huang <tjjh89017@hotmail.com>
2025-06-10 01:12:37 +08:00
Daniil Baturin
faa725ae12
Remove an emoji from an error message 2025-06-09 12:49:06 +01:00
Daniil Baturin
6b33a64184
Remove an emoji from an error message 2025-06-09 12:48:51 +01:00
Viacheslav Hletenko
2ecdb4f464 T7530: Build package binaries script should exit if repo is absent
The build package binaries script should exit if the repo is absent
or cannot be cloned

If a build package `repo-a` depends on the `repo-b` and the `repo-b`
cannot be cloned, then we shoud exit from the script to avoid
partly build dependencies

For example:
```
[[packages]]
name = "fake-repo"
commit_id = "v0.0.1"
scm_url = "https://github.com/vyos/fake-repo"

[[packages]]
name = "ethtool"
commit_id = "debian/1%6.10-1"
scm_url = "https://salsa.debian.org/kernel-team/ethtool"
```

If ethtool depends on some fake-package and this package cannot be
downloaded from the repo, then we shouldn't build the ethtool package
at all.
2025-06-09 09:41:34 +00:00
Gabin-CC
02c2e30622 T7453: handle dynamic partition mapping in raw image build
Enhanced the raw image creation logic to dynamically detect and assign
EFI and root partitions based on the number of partitions created by kpartx.

- Supports both 2-partition and 3-partition layouts
- Adds debug output for mapped partitions
- Avoids hardcoded assumptions about partition order
- Improves resilience in cloud-init and containerized build contexts

Fixes build failure when /dev/loopXp3 is missing or not mapped properly.

Signed-off-by: Gabin-CC <gabin.laurent@rte-international.com>
2025-06-06 20:59:22 +02:00
Gabin-CC
1cda2d42bb T7453: Enhance raw/qcow2 image creation
Description
This pull request introduces improvements to the raw_image.py script responsible for building raw disk images in the VyOS build process.

Main Changes
Added use of kpartx to reliably map EFI and root partitions from the loop device.
Introduced disk_details as an attribute on the BuildContext object to pass partition metadata through the image build steps.
Improved the __exit__ method for BuildContext to unmount all mount points and clean up kpartx mappings and loop devices, even in failure cases.
Fixed a crash in mount_image() when con.disk_details was not set.
Added useful debug logs for loop device usage and partition mapping.
Motivation
The previous implementation assumed partitions like /dev/loopXp3 would appear automatically, which is unreliable across some environments (especially containers or newer systems).

This PR makes the process more reliable by explicitly mapping partitions with kpartx, a tool designed for this purpose.

It also ensures proper resource cleanup by unmounting and detaching everything cleanly, preventing leaked loop devices or stale mount points.

Test Instructions

Flavor : cloud-init.toml
packages = [
  "cloud-init",
  "qemu-guest-agent"
]

image_format = ["qcow2"]
disk_size = 10

[boot_settings]
console_type = "ttyS0"

Run:

sudo ./build-vyos-image --architecture amd64 \
  --build-by "you@example.com" \
  --reuse-iso vyos-1.5-rolling-*.iso \
  cloud-init
Expected behavior:

The build completes without errors.
The .qcow2 image file is generated and bootable (e.g., in KVM or Proxmox).
Partitions are mounted correctly via /dev/mapper/loopXp*.

Signed-off-by: Gabin-CC <gabin.laurent@rte-international.com>
2025-06-06 20:58:04 +02:00
Viacheslav Hletenko
6bae49479f T4409: Fix Framed-Route with attr Accel-VRF-Name
If you use attribute Accel-VRF-Name we are expecting a
route in a specific VRF, the cuurent implementation
set the Framed-Route/Framed-IPv6-Route to the default VRf (no VRF)

Fixes this, so routes are installed in the proper VRF name
2025-03-13 12:00:58 +00:00
7 changed files with 969 additions and 20 deletions

View File

@ -63,22 +63,38 @@ class BuildContext:
return self
def __exit__(self, exc_type, exc_value, exc_tb):
def __exit__(self, exc_type, exc_value, traceback):
print(f"I: Tearing down the raw image build environment in {self.work_dir}")
cmd(f"""umount {self.squash_dir}/dev/""")
cmd(f"""umount {self.squash_dir}/proc/""")
cmd(f"""umount {self.squash_dir}/sys/""")
cmd(f"umount {self.squash_dir}/boot/efi")
cmd(f"umount {self.squash_dir}/boot")
cmd(f"""umount {self.squash_dir}""")
cmd(f"""umount {self.iso_dir}""")
cmd(f"""umount {self.raw_dir}""")
cmd(f"""umount {self.efi_dir}""")
for mount in [
f"{self.squash_dir}/dev/",
f"{self.squash_dir}/proc/",
f"{self.squash_dir}/sys/",
f"{self.squash_dir}/boot/efi",
f"{self.squash_dir}/boot",
f"{self.squash_dir}",
f"{self.iso_dir}",
f"{self.raw_dir}",
f"{self.efi_dir}"
]:
if os.path.ismount(mount):
try:
cmd(f"umount {mount}")
except Exception as e:
print(f"W: Failed to umount {mount}: {e}")
# Remove kpartx mappings
if self.loop_device:
cmd(f"""losetup -d {self.loop_device}""")
mapper_base = os.path.basename(self.loop_device)
try:
cmd(f"kpartx -d {self.loop_device}")
except Exception as e:
print(f"W: Failed to remove kpartx mappings for {mapper_base}: {e}")
try:
cmd(f"losetup -d {self.loop_device}")
except Exception as e:
print(f"W: Failed to detach loop device {self.loop_device}: {e}")
def create_disk(path, size):
cmd(f"""qemu-img create -f raw "{path}" {size}G""")
@ -106,14 +122,23 @@ def setup_loop_device(con, raw_file):
def mount_image(con):
import vyos.system.disk
from subprocess import Popen, PIPE, STDOUT
from re import match
try:
root = con.disk_details.partition['root']
efi = con.disk_details.partition['efi']
except (AttributeError, KeyError):
raise RuntimeError("E: No valid root or EFI partition found in disk details")
vyos.system.disk.filesystem_create(con.disk_details.partition['efi'], 'efi')
vyos.system.disk.filesystem_create(con.disk_details.partition['root'], 'ext4')
vyos.system.disk.filesystem_create(efi, 'efi')
vyos.system.disk.filesystem_create(root, 'ext4')
cmd(f"mount -t ext4 {con.disk_details.partition['root']} {con.raw_dir}")
print(f"I: Mounting root: {root} to {con.raw_dir}")
cmd(f"mount -t ext4 {root} {con.raw_dir}")
cmd(f"mount -t vfat {efi} {con.efi_dir}")
if not os.path.ismount(con.efi_dir):
cmd(f"mount -t vfat {con.disk_details.partition['efi']} {con.efi_dir}")
else:
print(f"I: {con.disk_details.partition['efi']} already mounted on {con.efi_dir}")
def install_image(con, version):
from glob import glob
@ -205,6 +230,36 @@ def create_raw_image(build_config, iso_file, work_dir):
create_disk(raw_file, build_config["disk_size"])
setup_loop_device(con, raw_file)
disk_details = parttable_create(con.loop_device, (int(build_config["disk_size"]) - 1) * 1024 * 1024)
# Map partitions using kpartx
print("I: Mapping partitions using kpartx...")
cmd(f"kpartx -av {con.loop_device}")
cmd("udevadm settle")
# Detect mapped partitions
from glob import glob
import time
mapper_base = os.path.basename(con.loop_device).replace("/dev/", "")
mapped_parts = sorted(glob(f"/dev/mapper/{mapper_base}p*"))
if not mapped_parts:
raise RuntimeError(f"E: No partitions were found in /dev/mapper for {mapper_base}")
print(f"I: Found mapped partitions: {mapped_parts}")
if len(mapped_parts) == 2:
# Assume [0] = EFI, [1] = root
disk_details.partition['efi'] = mapped_parts[0]
disk_details.partition['root'] = mapped_parts[1]
elif len(mapped_parts) >= 3:
# Common layout: [1] = EFI, [2] = root (skip 0 if it's BIOS boot)
disk_details.partition['efi'] = mapped_parts[1]
disk_details.partition['root'] = mapped_parts[2]
else:
raise RuntimeError(f"E: Unexpected partition layout: {mapped_parts}")
con.disk_details = disk_details
mount_image(con)
install_image(con, version)

View File

@ -17,6 +17,7 @@
import glob
import shutil
import sys
import toml
import os
@ -91,7 +92,11 @@ def build_package(package: list, patch_dir: Path) -> None:
# Check out the specific commit
run(['git', 'checkout', package['commit_id']], cwd=repo_dir, check=True)
except CalledProcessError as e:
print(f"Failed to clone or checkout for package '{repo_name}': {e}")
sys.exit(1)
try:
# The `pre_build_hook` is an optional configuration defined in `package.toml`.
# It executes after the repository is checked out and before the build process begins.
# This hook allows you to perform preparatory tasks, such as creating directories,

View File

@ -18,6 +18,7 @@
import datetime
import glob
import shutil
import sys
import toml
import os
import subprocess
@ -60,8 +61,12 @@ def clone_or_update_repo(repo_dir: Path, scm_url: str, commit_id: str) -> None:
run(['git', 'checkout', commit_id], cwd=repo_dir, check=True)
#run(['git', 'pull'], cwd=repo_dir, check=True)
else:
try:
run(['git', 'clone', scm_url, str(repo_dir)], check=True)
run(['git', 'checkout', commit_id], cwd=repo_dir, check=True)
except CalledProcessError as e:
print(f"Failed to clone or checkout: {e}")
sys.exit(1)
def create_tarball(package_name, source_dir=None):

View File

@ -0,0 +1,639 @@
From 5587c45d9e3264f45eba636941cf80b90f2f6186 Mon Sep 17 00:00:00 2001
From: Chris Hills <chris@brsk.co.uk>
Date: Thu, 29 Jun 2023 09:24:36 +0100
Subject: [PATCH 2/4] Add vrf support for Framed-Route and Framed-IPv6-Route
(cherry picked from commit 899dc375fe01672a5eae2d7f7db81edc0d2a4440)
---
accel-pppd/CMakeLists.txt | 4 +
accel-pppd/ctrl/ipoe/ipoe.c | 20 ++++
accel-pppd/ifcfg.c | 6 +-
accel-pppd/ipv6/dhcpv6.c | 8 ++
accel-pppd/libnetlink/iputils.c | 110 ++++++++++++++++-
accel-pppd/libnetlink/iputils.h | 11 ++
accel-pppd/libnetlink/rt_names.c | 196 +++++++++++++++++++++++++++++++
accel-pppd/libnetlink/rt_names.h | 14 +++
accel-pppd/radius/radius.c | 21 +++-
9 files changed, 384 insertions(+), 6 deletions(-)
create mode 100644 accel-pppd/libnetlink/rt_names.c
create mode 100644 accel-pppd/libnetlink/rt_names.h
diff --git a/accel-pppd/CMakeLists.txt b/accel-pppd/CMakeLists.txt
index ab8a350..c3995ea 100644
--- a/accel-pppd/CMakeLists.txt
+++ b/accel-pppd/CMakeLists.txt
@@ -123,6 +123,10 @@ ADD_EXECUTABLE(accel-pppd
main.c
)
+IF (DEFINED HAVE_VRF)
+ target_sources(accel-pppd PRIVATE libnetlink/rt_names.c)
+ENDIF (DEFINED HAVE_VRF)
+
TARGET_LINK_LIBRARIES(accel-pppd triton rt pthread ${crypto_lib} pcre)
set_property(TARGET accel-pppd PROPERTY CMAKE_SKIP_BUILD_RPATH FALSE)
set_property(TARGET accel-pppd PROPERTY CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 61b7c23..6f23fd6 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -1067,9 +1067,17 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
if (ses->ifindex == -1 && !serv->opt_ifcfg) {
if (!serv->opt_ip_unnumbered)
+#ifdef HAVE_VRF
+ iproute_add(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0, NULL);
+#else
iproute_add(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0);
+#endif
else
+#ifdef HAVE_VRF
+ iproute_add(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0, NULL);
+#else
iproute_add(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0);
+#endif
}
if (ses->l4_redirect)
@@ -1170,7 +1178,11 @@ static void ipoe_session_started(struct ap_session *s)
if (ses->ses.ipv4->peer_addr != ses->yiaddr)
//ipaddr_add_peer(ses->ses.ifindex, ses->router, ses->yiaddr); // breaks quagga
+#ifdef HAVE_VRF
+ iproute_add(ses->ses.ifindex, ses->router, ses->yiaddr, 0, conf_proto, 32, 0, NULL);
+#else
iproute_add(ses->ses.ifindex, ses->router, ses->yiaddr, 0, conf_proto, 32, 0);
+#endif
if (ses->ifindex != -1 && ses->xid) {
ses->dhcpv4 = dhcpv4_create(ses->ctrl.ctx, ses->ses.ifname, "");
@@ -1254,9 +1266,17 @@ static void ipoe_session_finished(struct ap_session *s)
} else if (ses->started) {
if (!serv->opt_ifcfg) {
if (!serv->opt_ip_unnumbered)
+#ifdef HAVE_VRF
+ iproute_del(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0, NULL);
+#else
iproute_del(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0);
+#endif
else
+#ifdef HAVE_VRF
+ iproute_del(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0, NULL);
+#else
iproute_del(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0);
+#endif
}
}
diff --git a/accel-pppd/ifcfg.c b/accel-pppd/ifcfg.c
index 3750060..3b1848e 100644
--- a/accel-pppd/ifcfg.c
+++ b/accel-pppd/ifcfg.c
@@ -234,7 +234,11 @@ void __export ap_session_ifdown(struct ap_session *ses)
if (!a->installed)
continue;
if (a->prefix_len > 64)
+#ifdef HAVE_VRF
+ ip6route_del(ses->ifindex, &a->addr, a->prefix_len, NULL, 0, 0, ses->vrf_name);
+#else
ip6route_del(ses->ifindex, &a->addr, a->prefix_len, NULL, 0, 0);
+#endif
else {
struct in6_addr addr;
memcpy(addr.s6_addr, &a->addr, 8);
@@ -376,4 +380,4 @@ int __export ap_session_vrf(struct ap_session *ses, const char *vrf_name, int le
return 0;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c
index 158771b..41e6c3f 100644
--- a/accel-pppd/ipv6/dhcpv6.c
+++ b/accel-pppd/ipv6/dhcpv6.c
@@ -159,7 +159,11 @@ static void ev_ses_finished(struct ap_session *ses)
if (pd->dp_active) {
struct ipv6db_addr_t *p;
list_for_each_entry(p, &ses->ipv6_dp->prefix_list, entry)
+#ifdef HAVE_VRF
+ ip6route_del(0, &p->addr, p->prefix_len, NULL, 0, 0, ses->vrf_name);
+#else
ip6route_del(0, &p->addr, p->prefix_len, NULL, 0, 0);
+#endif
}
ipdb_put_ipv6_prefix(ses, ses->ipv6_dp);
@@ -181,7 +185,11 @@ static void insert_dp_routes(struct ap_session *ses, struct dhcpv6_pd *pd, struc
addr = NULL;
list_for_each_entry(p, &ses->ipv6_dp->prefix_list, entry) {
+#ifdef HAVE_VRF
+ if (ip6route_add(ses->ifindex, &p->addr, p->prefix_len, addr, 0, 0, ses->vrf_name)) {
+#else
if (ip6route_add(ses->ifindex, &p->addr, p->prefix_len, addr, 0, 0)) {
+#endif
err = errno;
inet_ntop(AF_INET6, &p->addr, str1, sizeof(str1));
if (addr)
diff --git a/accel-pppd/libnetlink/iputils.c b/accel-pppd/libnetlink/iputils.c
index 23325fc..6c61fc2 100644
--- a/accel-pppd/libnetlink/iputils.c
+++ b/accel-pppd/libnetlink/iputils.c
@@ -11,7 +11,9 @@
#include <errno.h>
#include <time.h>
#include <sys/uio.h>
-//#include <linux/if_link.h>
+#ifdef HAVE_VRF
+#include <linux/if_link.h>
+#endif
//#include <linux/if_addr.h>
//#include <linux/rtnetlink.h>
#include <linux/fib_rules.h>
@@ -21,6 +23,9 @@
#include "libnetlink.h"
#include "iputils.h"
#include "ap_net.h"
+#ifdef HAVE_VRF
+#include "rt_names.h"
+#endif
#ifdef ACCEL_DP
#define _malloc(x) malloc(x)
@@ -457,7 +462,82 @@ int __export ipaddr_del_peer(int ifindex, in_addr_t addr, in_addr_t peer)
return r;
}
+#ifdef HAVE_VRF
+__u32 ipvrf_get_table(const char *vrf_name)
+{
+ struct iplink_req {
+ struct nlmsghdr n;
+ 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;
+ int len;
+ __u32 tb_id = RT_TABLE_MAIN;
+
+ log_ppp_info2("utils: getting route table for %s\n", vrf_name);
+
+ if (!vrf_name)
+ return tb_id;
+
+ memset(&req, 0, sizeof(req) - 4096);
+
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = RTM_GETLINK;
+ req.i.ifi_family = AF_UNSPEC;
+
+ addattr_l(&req.n, 4096, IFLA_IFNAME, vrf_name, strlen(vrf_name));
+
+ if (rtnl_talk(rth, &req.n, 0, 0, &req.n, NULL, NULL, 0) < 0) {
+ if (errno == ENODEV && !strcmp(vrf_name, "default"))
+ if (rtnl_rttable_a2n(&tb_id, "main"))
+ log_ppp_error(
+ "BUG: route table \"main\" not found.\n");
+ return tb_id;
+ }
+
+ ifi = NLMSG_DATA(&req.n);
+
+ len = req.n.nlmsg_len;
+
+ len -= NLMSG_LENGTH(sizeof(*ifi));
+ if (len < 0)
+ goto out;
+
+ parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+
+ if (!tb[IFLA_LINKINFO])
+ goto out;
+
+ parse_rtattr_nested(li, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+
+ if (!li[IFLA_INFO_KIND] || !li[IFLA_INFO_DATA])
+ goto out;
+
+ if (strcmp(RTA_DATA(li[IFLA_INFO_KIND]), "vrf"))
+ goto out;
+
+ parse_rtattr_nested(vrf_attr, IFLA_VRF_MAX, li[IFLA_INFO_DATA]);
+ if (vrf_attr[IFLA_VRF_TABLE])
+ tb_id = *(__u32 *)RTA_DATA(vrf_attr[IFLA_VRF_TABLE]);
+
+ if (!tb_id)
+ log_ppp_error("BUG: VRF %s is missing table id\n", vrf_name);
+
+out:
+ return tb_id;
+}
+#endif
+
+#ifdef HAVE_VRF
+int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio, const char *vrf_name)
+#else
int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio)
+#endif
{
struct ipaddr_req {
struct nlmsghdr n;
@@ -472,11 +552,17 @@ int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
memset(&req, 0, sizeof(req) - 4096);
+#ifdef HAVE_VRF
+ __u32 rt_table = ipvrf_get_table(vrf_name);
+#else
+ __u32 rt_table = RT_TABLE_MAIN;
+#endif
+
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
req.n.nlmsg_type = RTM_NEWROUTE;
req.i.rtm_family = AF_INET;
- req.i.rtm_table = RT_TABLE_MAIN;
+ req.i.rtm_table = rt_table;
req.i.rtm_scope = gw ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK;
req.i.rtm_protocol = proto;
req.i.rtm_type = RTN_UNICAST;
@@ -500,7 +586,11 @@ int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
return r;
}
+#ifdef HAVE_VRF
+int __export iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio, const char *vrf_name)
+#else
int __export iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio)
+#endif
{
struct ipaddr_req {
struct nlmsghdr n;
@@ -543,7 +633,11 @@ int __export iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
return r;
}
+#ifdef HAVE_VRF
+int __export ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio, const char *vrf_name)
+#else
int __export ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio)
+#endif
{
struct ipaddr_req {
struct nlmsghdr n;
@@ -558,11 +652,17 @@ int __export ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len,
memset(&req, 0, sizeof(req) - 4096);
+#ifdef HAVE_VRF
+ __u32 rt_table = ipvrf_get_table(vrf_name);
+#else
+ __u32 rt_table = RT_TABLE_MAIN;
+#endif
+
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
req.n.nlmsg_type = RTM_NEWROUTE;
req.i.rtm_family = AF_INET6;
- req.i.rtm_table = RT_TABLE_MAIN;
+ req.i.rtm_table = rt_table;
req.i.rtm_scope = RT_SCOPE_UNIVERSE;
req.i.rtm_protocol = proto;
req.i.rtm_type = RTN_UNICAST;
@@ -584,7 +684,11 @@ int __export ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len,
return r;
}
+#ifdef HAVE_VRF
+int __export ip6route_del(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio, const char *vrf_name)
+#else
int __export ip6route_del(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio)
+#endif
{
struct ipaddr_req {
struct nlmsghdr n;
diff --git a/accel-pppd/libnetlink/iputils.h b/accel-pppd/libnetlink/iputils.h
index 9292cea..c3063f4 100644
--- a/accel-pppd/libnetlink/iputils.h
+++ b/accel-pppd/libnetlink/iputils.h
@@ -4,6 +4,7 @@
#include <linux/if_link.h>
#include <netinet/in.h>
#include <stdint.h>
+#include <config.h>
typedef int (*iplink_list_func)(int index, int flags, const char *name, int iflink, int vid, void *arg);
@@ -20,12 +21,22 @@ int ipaddr_add_peer(int ifindex, in_addr_t addr, in_addr_t peer_addr);
int ipaddr_del(int ifindex, in_addr_t addr, int mask);
int ipaddr_del_peer(int ifindex, in_addr_t addr, in_addr_t peer);
+#ifdef HAVE_VRF
+int iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio, const char *vrf_name);
+int iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio, const char *vrf_name);
+#else
int iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio);
int iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio);
+#endif
in_addr_t iproute_get(in_addr_t dst, in_addr_t *gw);
+#ifdef HAVE_VRF
+int ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio, const char *vrf_name);
+int ip6route_del(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio, const char *vrf_name);
+#else
int ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio);
int ip6route_del(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio);
+#endif
int ip6addr_add(int ifindex, struct in6_addr *addr, int prefix_len);
int ip6addr_add_peer(int ifindex, struct in6_addr *addr, struct in6_addr *peer_addr);
int ip6addr_del(int ifindex, struct in6_addr *addr, int prefix_len);
diff --git a/accel-pppd/libnetlink/rt_names.c b/accel-pppd/libnetlink/rt_names.c
new file mode 100644
index 0000000..5591a67
--- /dev/null
+++ b/accel-pppd/libnetlink/rt_names.c
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * rt_names.c rtnetlink names DB.
+ *
+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <dirent.h>
+#include <limits.h>
+
+#include <asm/types.h>
+#include <linux/rtnetlink.h>
+
+#include "rt_names.h"
+#include "utils.h"
+
+#define NAME_MAX_LEN 512
+#define CONFDIR "/etc/iproute2"
+
+int numeric;
+
+struct rtnl_hash_entry {
+ struct rtnl_hash_entry *next;
+ const char *name;
+ unsigned int id;
+};
+
+static int fread_id_name(FILE *fp, int *id, char *namebuf)
+{
+ char buf[NAME_MAX_LEN];
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ char *p = buf;
+
+ while (*p == ' ' || *p == '\t')
+ p++;
+
+ if (*p == '#' || *p == '\n' || *p == 0)
+ continue;
+
+ if (sscanf(p, "0x%x %s\n", id, namebuf) != 2 &&
+ sscanf(p, "0x%x %s #", id, namebuf) != 2 &&
+ sscanf(p, "%d %s\n", id, namebuf) != 2 &&
+ sscanf(p, "%d %s #", id, namebuf) != 2) {
+ strcpy(namebuf, p);
+ return -1;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+static void
+rtnl_hash_initialize(const char *file, struct rtnl_hash_entry **hash, int size)
+{
+ struct rtnl_hash_entry *entry;
+ FILE *fp;
+ int id;
+ char namebuf[NAME_MAX_LEN] = {0};
+ int ret;
+
+ fp = fopen(file, "r");
+ if (!fp)
+ return;
+
+ while ((ret = fread_id_name(fp, &id, &namebuf[0]))) {
+ if (ret == -1) {
+ fprintf(stderr, "Database %s is corrupted at %s\n",
+ file, namebuf);
+ fclose(fp);
+ return;
+ }
+
+ if (id < 0)
+ continue;
+
+ entry = malloc(sizeof(*entry));
+ if (entry == NULL) {
+ fprintf(stderr, "malloc error: for entry\n");
+ break;
+ }
+ entry->id = id;
+ entry->name = strdup(namebuf);
+ entry->next = hash[id & (size - 1)];
+ hash[id & (size - 1)] = entry;
+ }
+ fclose(fp);
+}
+
+static struct rtnl_hash_entry dflt_table_entry = { .name = "default" };
+static struct rtnl_hash_entry main_table_entry = { .name = "main" };
+static struct rtnl_hash_entry local_table_entry = { .name = "local" };
+
+static struct rtnl_hash_entry *rtnl_rttable_hash[256] = {
+ [RT_TABLE_DEFAULT] = &dflt_table_entry,
+ [RT_TABLE_MAIN] = &main_table_entry,
+ [RT_TABLE_LOCAL] = &local_table_entry,
+};
+
+static int rtnl_rttable_init;
+
+static void rtnl_rttable_initialize(void)
+{
+ struct dirent *de;
+ DIR *d;
+ int i;
+
+ rtnl_rttable_init = 1;
+ for (i = 0; i < 256; i++) {
+ if (rtnl_rttable_hash[i])
+ rtnl_rttable_hash[i]->id = i;
+ }
+ rtnl_hash_initialize(CONFDIR "/rt_tables",
+ rtnl_rttable_hash, 256);
+
+ d = opendir(CONFDIR "/rt_tables.d");
+ if (!d)
+ return;
+
+ while ((de = readdir(d)) != NULL) {
+ char path[PATH_MAX];
+ size_t len;
+
+ if (*de->d_name == '.')
+ continue;
+
+ /* only consider filenames ending in '.conf' */
+ len = strlen(de->d_name);
+ if (len <= 5)
+ continue;
+ if (strcmp(de->d_name + len - 5, ".conf"))
+ continue;
+
+ snprintf(path, sizeof(path),
+ CONFDIR "/rt_tables.d/%s", de->d_name);
+ rtnl_hash_initialize(path, rtnl_rttable_hash, 256);
+ }
+ closedir(d);
+}
+
+const char *rtnl_rttable_n2a(__u32 id, char *buf, int len)
+{
+ struct rtnl_hash_entry *entry;
+
+ if (!rtnl_rttable_init)
+ rtnl_rttable_initialize();
+ entry = rtnl_rttable_hash[id & 255];
+ while (entry && entry->id != id)
+ entry = entry->next;
+ if (!numeric && entry)
+ return entry->name;
+ snprintf(buf, len, "%u", id);
+ return buf;
+}
+
+int rtnl_rttable_a2n(__u32 *id, const char *arg)
+{
+ static const char *cache;
+ static unsigned long res;
+ struct rtnl_hash_entry *entry;
+ char *end;
+ unsigned long i;
+
+ if (cache && strcmp(cache, arg) == 0) {
+ *id = res;
+ return 0;
+ }
+
+ if (!rtnl_rttable_init)
+ rtnl_rttable_initialize();
+
+ for (i = 0; i < 256; i++) {
+ entry = rtnl_rttable_hash[i];
+ while (entry && strcmp(entry->name, arg))
+ entry = entry->next;
+ if (entry) {
+ cache = entry->name;
+ res = entry->id;
+ *id = res;
+ return 0;
+ }
+ }
+
+ i = strtoul(arg, &end, 0);
+ if (!end || end == arg || *end || i > RT_TABLE_MAX)
+ return -1;
+ *id = i;
+ return 0;
+}
diff --git a/accel-pppd/libnetlink/rt_names.h b/accel-pppd/libnetlink/rt_names.h
new file mode 100644
index 0000000..2ba6fe9
--- /dev/null
+++ b/accel-pppd/libnetlink/rt_names.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef RT_NAMES_H_
+#define RT_NAMES_H_ 1
+
+#include <asm/types.h>
+
+const char *rtnl_rttable_n2a(__u32 id, char *buf, int len);
+const char *rtnl_dsfield_get_name(int id);
+
+int rtnl_rttable_a2n(__u32 *id, const char *arg);
+
+extern int numeric;
+
+#endif
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index 2406ba0..a45666f 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -313,6 +313,7 @@ int rad_proc_attrs(struct rad_req_t *req)
} else if (attr->vendor->id == VENDOR_Accel_PPP) {
switch (attr->attr->id) {
case Accel_VRF_Name:
+ log_ppp_info2("radius: setting vrf_name to %s\n", attr->val.string);
if (rpd->ses->vrf_name)
_free(rpd->ses->vrf_name);
rpd->ses->vrf_name = _malloc(attr->len + 1);
@@ -642,15 +643,23 @@ static void ses_started(struct ap_session *ses)
char nbuf[INET6_ADDRSTRLEN];
char gwbuf[INET6_ADDRSTRLEN];
+#ifdef HAVE_VRF
+ if (ip6route_add(gw_spec ? 0 : rpd->ses->ifindex, &fr6->prefix, fr6->plen, gw_spec ? &fr6->gw : NULL, 3, fr6->prio, rpd->ses->vrf_name)) {
+#else
if (ip6route_add(gw_spec ? 0 : rpd->ses->ifindex, &fr6->prefix, fr6->plen, gw_spec ? &fr6->gw : NULL, 3, fr6->prio)) {
+#endif
log_ppp_warn("radius: failed to add route %s/%hhu %s %u\n",
- u_ip6str(&fr6->prefix, nbuf), fr6->plen,
- u_ip6str(&fr6->gw, gwbuf), fr6->prio);
+ u_ip6str(&fr6->prefix, nbuf), fr6->plen,
+ u_ip6str(&fr6->gw, gwbuf), fr6->prio);
}
}
for (fr = rpd->fr; fr; fr = fr->next) {
+#ifdef HAVE_VRF
+ if (iproute_add(fr->gw ? 0 : rpd->ses->ifindex, 0, fr->dst, fr->gw, 3, fr->mask, fr->prio, rpd->ses->vrf_name)) {
+#else
if (iproute_add(fr->gw ? 0 : rpd->ses->ifindex, 0, fr->dst, fr->gw, 3, fr->mask, fr->prio)) {
+#endif
char dst[17], gw[17];
u_inet_ntoa(fr->dst, dst);
u_inet_ntoa(fr->gw, gw);
@@ -689,12 +698,20 @@ static void ses_finishing(struct ap_session *ses)
* when the interface is removed.
*/
if (!IN6_IS_ADDR_UNSPECIFIED(&fr6->gw))
+#ifdef HAVE_VRF
+ ip6route_del(0, &fr6->prefix, fr6->plen, &fr6->gw, 3, fr6->prio, rpd->ses->vrf_name);
+#else
ip6route_del(0, &fr6->prefix, fr6->plen, &fr6->gw, 3, fr6->prio);
+#endif
}
for (fr = rpd->fr; fr; fr = fr->next) {
if (fr->gw)
+#ifdef HAVE_VRF
+ iproute_del(0, 0, fr->dst, fr->gw, 3, fr->mask, fr->prio, rpd->ses->vrf_name);
+#else
iproute_del(0, 0, fr->dst, fr->gw, 3, fr->mask, fr->prio);
+#endif
}
if (rpd->acct_started || rpd->acct_req)
--
2.39.5

View File

@ -0,0 +1,213 @@
From 4898832b90a6b929b8316fe55085b14c3afcf4a8 Mon Sep 17 00:00:00 2001
From: Chris Hills <chris@brsk.co.uk>
Date: Mon, 3 Jul 2023 14:42:22 +0100
Subject: [PATCH 3/4] Simplify implementation of vrf support for
iproute_add/del
(cherry picked from commit 85cbd27bd440e0a4836bb9e03c933e05fd321769)
---
accel-pppd/ctrl/ipoe/ipoe.c | 24 ++----------------------
accel-pppd/libnetlink/iputils.c | 16 ----------------
accel-pppd/libnetlink/iputils.h | 5 -----
accel-pppd/radius/radius.c | 16 ----------------
accel-pppd/session.c | 1 +
5 files changed, 3 insertions(+), 59 deletions(-)
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 6f23fd6..3a6c85b 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -1021,9 +1021,9 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
in_addr_t gw;
iproute_get(ses->router, &gw, NULL);
if (gw)
- iproute_add(0, ses->siaddr, ses->yiaddr, gw, conf_proto, 32);
+ iproute_add(0, ses->siaddr, ses->yiaddr, gw, conf_proto, 32, NULL);
else
- iproute_add(0, ses->siaddr, ses->router, gw, conf_proto, 32);
+ iproute_add(0, ses->siaddr, ses->router, gw, conf_proto, 32, NULL);
}*/
if (serv->opt_mode == MODE_L3)
@@ -1067,17 +1067,9 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
if (ses->ifindex == -1 && !serv->opt_ifcfg) {
if (!serv->opt_ip_unnumbered)
-#ifdef HAVE_VRF
iproute_add(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0, NULL);
-#else
- iproute_add(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0);
-#endif
else
-#ifdef HAVE_VRF
iproute_add(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0, NULL);
-#else
- iproute_add(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0);
-#endif
}
if (ses->l4_redirect)
@@ -1178,11 +1170,7 @@ static void ipoe_session_started(struct ap_session *s)
if (ses->ses.ipv4->peer_addr != ses->yiaddr)
//ipaddr_add_peer(ses->ses.ifindex, ses->router, ses->yiaddr); // breaks quagga
-#ifdef HAVE_VRF
iproute_add(ses->ses.ifindex, ses->router, ses->yiaddr, 0, conf_proto, 32, 0, NULL);
-#else
- iproute_add(ses->ses.ifindex, ses->router, ses->yiaddr, 0, conf_proto, 32, 0);
-#endif
if (ses->ifindex != -1 && ses->xid) {
ses->dhcpv4 = dhcpv4_create(ses->ctrl.ctx, ses->ses.ifname, "");
@@ -1266,17 +1254,9 @@ static void ipoe_session_finished(struct ap_session *s)
} else if (ses->started) {
if (!serv->opt_ifcfg) {
if (!serv->opt_ip_unnumbered)
-#ifdef HAVE_VRF
iproute_del(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0, NULL);
-#else
- iproute_del(serv->ifindex, ses->router, ses->yiaddr, 0, conf_proto, ses->mask, 0);
-#endif
else
-#ifdef HAVE_VRF
iproute_del(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0, NULL);
-#else
- iproute_del(serv->ifindex, serv->opt_src ?: ses->router, ses->yiaddr, 0, conf_proto, 32, 0);
-#endif
}
}
diff --git a/accel-pppd/libnetlink/iputils.c b/accel-pppd/libnetlink/iputils.c
index 6c61fc2..60eca8b 100644
--- a/accel-pppd/libnetlink/iputils.c
+++ b/accel-pppd/libnetlink/iputils.c
@@ -533,11 +533,7 @@ out:
}
#endif
-#ifdef HAVE_VRF
int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio, const char *vrf_name)
-#else
-int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio)
-#endif
{
struct ipaddr_req {
struct nlmsghdr n;
@@ -586,11 +582,7 @@ int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
return r;
}
-#ifdef HAVE_VRF
int __export iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio, const char *vrf_name)
-#else
-int __export iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio)
-#endif
{
struct ipaddr_req {
struct nlmsghdr n;
@@ -633,11 +625,7 @@ int __export iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
return r;
}
-#ifdef HAVE_VRF
int __export ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio, const char *vrf_name)
-#else
-int __export ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio)
-#endif
{
struct ipaddr_req {
struct nlmsghdr n;
@@ -684,11 +672,7 @@ int __export ip6route_add(int ifindex, const struct in6_addr *dst, int pref_len,
return r;
}
-#ifdef HAVE_VRF
int __export ip6route_del(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio, const char *vrf_name)
-#else
-int __export ip6route_del(int ifindex, const struct in6_addr *dst, int pref_len, const struct in6_addr *gw, int proto, uint32_t prio)
-#endif
{
struct ipaddr_req {
struct nlmsghdr n;
diff --git a/accel-pppd/libnetlink/iputils.h b/accel-pppd/libnetlink/iputils.h
index c3063f4..d3a93f4 100644
--- a/accel-pppd/libnetlink/iputils.h
+++ b/accel-pppd/libnetlink/iputils.h
@@ -21,13 +21,8 @@ int ipaddr_add_peer(int ifindex, in_addr_t addr, in_addr_t peer_addr);
int ipaddr_del(int ifindex, in_addr_t addr, int mask);
int ipaddr_del_peer(int ifindex, in_addr_t addr, in_addr_t peer);
-#ifdef HAVE_VRF
int iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio, const char *vrf_name);
int iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio, const char *vrf_name);
-#else
-int iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio);
-int iproute_del(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw, int proto, int mask, uint32_t prio);
-#endif
in_addr_t iproute_get(in_addr_t dst, in_addr_t *gw);
#ifdef HAVE_VRF
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index a45666f..9d567b7 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -643,11 +643,7 @@ static void ses_started(struct ap_session *ses)
char nbuf[INET6_ADDRSTRLEN];
char gwbuf[INET6_ADDRSTRLEN];
-#ifdef HAVE_VRF
if (ip6route_add(gw_spec ? 0 : rpd->ses->ifindex, &fr6->prefix, fr6->plen, gw_spec ? &fr6->gw : NULL, 3, fr6->prio, rpd->ses->vrf_name)) {
-#else
- if (ip6route_add(gw_spec ? 0 : rpd->ses->ifindex, &fr6->prefix, fr6->plen, gw_spec ? &fr6->gw : NULL, 3, fr6->prio)) {
-#endif
log_ppp_warn("radius: failed to add route %s/%hhu %s %u\n",
u_ip6str(&fr6->prefix, nbuf), fr6->plen,
u_ip6str(&fr6->gw, gwbuf), fr6->prio);
@@ -655,11 +651,7 @@ static void ses_started(struct ap_session *ses)
}
for (fr = rpd->fr; fr; fr = fr->next) {
-#ifdef HAVE_VRF
if (iproute_add(fr->gw ? 0 : rpd->ses->ifindex, 0, fr->dst, fr->gw, 3, fr->mask, fr->prio, rpd->ses->vrf_name)) {
-#else
- if (iproute_add(fr->gw ? 0 : rpd->ses->ifindex, 0, fr->dst, fr->gw, 3, fr->mask, fr->prio)) {
-#endif
char dst[17], gw[17];
u_inet_ntoa(fr->dst, dst);
u_inet_ntoa(fr->gw, gw);
@@ -698,20 +690,12 @@ static void ses_finishing(struct ap_session *ses)
* when the interface is removed.
*/
if (!IN6_IS_ADDR_UNSPECIFIED(&fr6->gw))
-#ifdef HAVE_VRF
ip6route_del(0, &fr6->prefix, fr6->plen, &fr6->gw, 3, fr6->prio, rpd->ses->vrf_name);
-#else
- ip6route_del(0, &fr6->prefix, fr6->plen, &fr6->gw, 3, fr6->prio);
-#endif
}
for (fr = rpd->fr; fr; fr = fr->next) {
if (fr->gw)
-#ifdef HAVE_VRF
iproute_del(0, 0, fr->dst, fr->gw, 3, fr->mask, fr->prio, rpd->ses->vrf_name);
-#else
- iproute_del(0, 0, fr->dst, fr->gw, 3, fr->mask, fr->prio);
-#endif
}
if (rpd->acct_started || rpd->acct_req)
diff --git a/accel-pppd/session.c b/accel-pppd/session.c
index c01417f..fedb6f5 100644
--- a/accel-pppd/session.c
+++ b/accel-pppd/session.c
@@ -68,6 +68,7 @@ void __export ap_session_init(struct ap_session *ses)
ses->ifindex = -1;
ses->unit_idx = -1;
ses->net = net;
+ ses->vrf_name = NULL;
}
void __export ap_session_set_ifindex(struct ap_session *ses)
--
2.39.5

View File

@ -0,0 +1,26 @@
From a959ab0c0d659a8b314b98bb577a79ec9ed3542c Mon Sep 17 00:00:00 2001
From: Chris Hills <chris@brsk.co.uk>
Date: Tue, 11 Jul 2023 10:14:52 +0100
Subject: [PATCH 4/4] Fix whitespace in accel-pppd/libnetlink/iputils.c
(cherry picked from commit 10d2fba58928dcb4604a04169cbb3a8c9e8a172f)
---
accel-pppd/libnetlink/iputils.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/accel-pppd/libnetlink/iputils.c b/accel-pppd/libnetlink/iputils.c
index 60eca8b..afe2380 100644
--- a/accel-pppd/libnetlink/iputils.c
+++ b/accel-pppd/libnetlink/iputils.c
@@ -551,7 +551,7 @@ int __export iproute_add(int ifindex, in_addr_t src, in_addr_t dst, in_addr_t gw
#ifdef HAVE_VRF
__u32 rt_table = ipvrf_get_table(vrf_name);
#else
- __u32 rt_table = RT_TABLE_MAIN;
+ __u32 rt_table = RT_TABLE_MAIN;
#endif
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
--
2.39.5

View File

@ -13,3 +13,9 @@ sudo dpkg -i ../libnftnl*.deb
sudo mk-build-deps --install --tool 'apt-get --yes --no-install-recommends'
dpkg-buildpackage -uc -us -tc -b
"""
[dependencies]
packages = [
"asciidoc-base",
"bison"
]