Merge pull request #503 from c-po/isc-dhcp-T5965

isc-dhcp: T5965: add custom package build with dhclient patches for WWAN
This commit is contained in:
Daniil Baturin 2024-02-15 15:19:15 +00:00 committed by GitHub
commit 4d850fd1f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 549 additions and 0 deletions

1
packages/isc-dhcp/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
isc-dhcp/

32
packages/isc-dhcp/Jenkinsfile vendored Normal file
View File

@ -0,0 +1,32 @@
// Copyright (C) 2024 VyOS maintainers and contributors
//
// This program is free software; you can redistribute it and/or modify
// in order to easy exprort images built to "external" world
// it under the terms of the GNU General Public License version 2 or later as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
@NonCPS
// Using a version specifier library, use 'current' branch. The underscore (_)
// is not a typo! You need this underscore if the line immediately after the
// @Library annotation is not an import statement!
@Library('vyos-build@current')_
// NOTE: we can build with -d as the libbpf dependency is installed manually
// and not via a DEB package
def pkgList = [
['name': 'isc-dhcp',
'scmCommit': 'debian/4.4.3-P1-4',
'scmUrl': 'https://salsa.debian.org/debian/isc-dhcp',
'buildCmd': 'sudo mk-build-deps --install --tool "apt-get --yes --no-install-recommends"; cd ..; ./build.sh'],
]
// Start package build using library function from https://github.com/vyos/vyos-build
buildPackage('isc-dhcp', pkgList, null, true, "**/packages/isc-dhcp/**")

21
packages/isc-dhcp/build.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
CWD=$(pwd)
set -e
SRC=isc-dhcp
if [ ! -d ${SRC} ]; then
echo "Source directory does not exists, please 'git clone'"
exit 1
fi
cd ${SRC}
PATCH_DIR=${CWD}/patches
for patch in $(ls ${PATCH_DIR})
do
echo "I: Copy patch: ${PATCH_DIR}/${patch}"
cp ${PATCH_DIR}/${patch} debian/patches/${patch}
echo ${patch} >> debian/patches/series
done
echo "I: Build Debian Package"
dpkg-buildpackage -uc -us -tc -b -d

View File

@ -0,0 +1,248 @@
From 8d9e8ace96ad9e2dba9f2d4069228dee5daf6772 Mon Sep 17 00:00:00 2001
From: Loic Poulain <loic.poulain@linaro.org>
Date: Mon, 2 Nov 2020 06:42:12 -0500
Subject: [PATCH 1/4] Add support for raw IP interface type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Under linux some devices can expose raw IP interfaces, such as WWAN
modems. In that case IP data is not encapsulated in any lower level
protocol.
dhclient does not support this currently and this patch adds support
for such pure IP interfaces.
The original patch comes from Bjørn Mork on Network-Manage mailing list:
https://mail.gnome.org/archives/networkmanager-list/2015-December/msg00044.html
---
common/bpf.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-
common/lpf.c | 59 +++++++++++++++++++++++++++++++++++++-----------
common/packet.c | 7 ++++++
includes/dhcp.h | 1 +
4 files changed, 113 insertions(+), 14 deletions(-)
diff --git a/common/bpf.c b/common/bpf.c
index 658e5db..0c08574 100644
--- a/common/bpf.c
+++ b/common/bpf.c
@@ -198,6 +198,34 @@ struct bpf_insn dhcp_bpf_filter [] = {
BPF_STMT (BPF_RET + BPF_K, 0),
};
+int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
+
+struct bpf_insn dhcp_bpf_pureip_filter [] = {
+ /* Make sure it's a UDP packet... */
+ BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 9),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
+
+ /* Make sure this isn't a fragment... */
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6),
+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
+
+ /* Get the IP header length... */
+ BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 0),
+
+ /* Make sure it's to the right port... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_IND, 2),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 0, 1), /* patch */
+
+ /* If we passed all the tests, ask for the whole packet. */
+ BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
+
+ /* Otherwise, drop it. */
+ BPF_STMT(BPF_RET+BPF_K, 0),
+};
+
+int dhcp_bpf_pureip_filter_len =
+ sizeof dhcp_bpf_pureip_filter / sizeof (struct bpf_insn);
+
#if defined(RELAY_PORT)
/*
* For relay port extension
@@ -235,13 +263,43 @@ struct bpf_insn dhcp_bpf_relay_filter [] = {
int dhcp_bpf_relay_filter_len =
sizeof dhcp_bpf_relay_filter / sizeof (struct bpf_insn);
+
+struct bpf_insn dhcp_bpf_pureip_relay_filter [] = {
+ /* Make sure it's a UDP packet... */
+ BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 9),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 8),
+
+ /* Make sure this isn't a fragment... */
+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6),
+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 6, 0),
+
+ /* Get the IP header length... */
+ BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 0),
+
+ /* Make sure it's to the right port... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 2, 0), /* patch */
+
+ /* relay can have an alternative port... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 0, 1), /* patch */
+
+ /* If we passed all the tests, ask for the whole packet. */
+ BPF_STMT (BPF_RET + BPF_K, (u_int)-1),
+
+ /* Otherwise, drop it. */
+ BPF_STMT (BPF_RET + BPF_K, 0),
+};
+
+int dhcp_bpf_pureip_relay_filter_len =
+ sizeof dhcp_bpf_pureip_relay_filter / sizeof (struct bpf_insn);
+
#endif
#if defined (DEC_FDDI)
struct bpf_insn *bpf_fddi_filter = NULL;
#endif
-int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
#if defined (HAVE_TR_SUPPORT)
struct bpf_insn dhcp_bpf_tr_filter [] = {
/* accept all token ring packets due to variable length header */
diff --git a/common/lpf.c b/common/lpf.c
index bb8822a..d8f34a4 100644
--- a/common/lpf.c
+++ b/common/lpf.c
@@ -177,9 +177,15 @@ void if_deregister_send (info)
extern struct sock_filter dhcp_bpf_filter [];
extern int dhcp_bpf_filter_len;
+extern struct sock_filter dhcp_bpf_pureip_filter [];
+extern int dhcp_bpf_pureip_filter_len;
+
#if defined(RELAY_PORT)
extern struct sock_filter dhcp_bpf_relay_filter [];
extern int dhcp_bpf_relay_filter_len;
+
+extern struct sock_filter dhcp_bpf_pureip_relay_filter [];
+extern int dhcp_bpf_pureip_relay_filter_len;
#endif
#if defined (HAVE_TR_SUPPORT)
@@ -249,31 +255,52 @@ void if_deregister_receive (info)
static void lpf_gen_filter_setup (info)
struct interface_info *info;
{
+ int pure_ip = info -> hw_address.hbuf [0] == HTYPE_PUREIP;
struct sock_fprog p;
memset(&p, 0, sizeof(p));
- /* Set up the bpf filter program structure. This is defined in
- bpf.c */
- p.len = dhcp_bpf_filter_len;
- p.filter = dhcp_bpf_filter;
+ /* Set up the bpf filter program structure and patch port(s).
+ *
+ * This is defined in bpf.c, XXX changes to filter program may
+ * require changes to the insn number(s) used below! XXX
+ */
+
+ if (pure_ip) {
+ p.len = dhcp_bpf_pureip_filter_len;
+ p.filter = dhcp_bpf_pureip_filter;
+
+ /* patch port */
+ dhcp_bpf_pureip_filter [6].k = ntohs (local_port);
+ } else {
+ p.len = dhcp_bpf_filter_len;
+ p.filter = dhcp_bpf_filter;
+
+ /* patch port */
+ dhcp_bpf_filter [8].k = ntohs (local_port);
+ }
- /* Patch the server port into the LPF program...
- XXX changes to filter program may require changes
- to the insn number(s) used below! XXX */
#if defined(RELAY_PORT)
- if (relay_port) {
- /*
- * If user defined relay UDP port, we need to filter
- * also on the user UDP port.
- */
+ /*
+ * If user defined relay UDP port, we need to filter
+ * also on the user UDP port.
+ */
+ if (relay_port && pure_ip) {
+ p.len = dhcp_bpf_pureip_relay_filter_len;
+ p.filter = dhcp_bpf_pureip_relay_filter;
+
+ /* patch ports */
+ dhcp_bpf_pureip_relay_filter [6].k = ntohs (local_port);
+ dhcp_bpf_pureip_relay_filter [8].k = ntohs (relay_port);
+ } else if (relay_port) {
p.len = dhcp_bpf_relay_filter_len;
p.filter = dhcp_bpf_relay_filter;
+ /* patch ports */
+ dhcp_bpf_relay_filter [8].k = ntohs (local_port);
dhcp_bpf_relay_filter [10].k = ntohs (relay_port);
}
#endif
- dhcp_bpf_filter [8].k = ntohs (local_port);
if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
sizeof p) < 0) {
@@ -578,6 +605,12 @@ get_hw_addr(const char *name, struct hardware *hw) {
hw->hbuf[3] = 0xbe;
hw->hbuf[4] = 0xef;
break;
+#endif
+#ifdef ARPHRD_RAWIP
+ case ARPHRD_RAWIP:
+ hw->hlen = 1;
+ hw->hbuf[0] = HTYPE_PUREIP;
+ break;
#endif
default:
log_fatal("Unsupported device type %ld for \"%s\"",
diff --git a/common/packet.c b/common/packet.c
index 49795c4..6745db7 100644
--- a/common/packet.c
+++ b/common/packet.c
@@ -119,6 +119,10 @@ void assemble_hw_header (interface, buf, bufix, to)
case HTYPE_INFINIBAND:
log_error("Attempt to assemble hw header for infiniband");
break;
+ case HTYPE_PUREIP:
+ /* Nothing to do, there is no hw header */
+ *bufix = 0;
+ break;
case HTYPE_ETHER:
default:
assemble_ethernet_header(interface, buf, bufix, to);
@@ -219,6 +223,9 @@ ssize_t decode_hw_header (interface, buf, bufix, from)
case HTYPE_INFINIBAND:
log_error("Attempt to decode hw header for infiniband");
return (0);
+ case HTYPE_PUREIP:
+ /* Nothing to do, there is no hw header */
+ return 0;
case HTYPE_ETHER:
default:
return (decode_ethernet_header(interface, buf, bufix, from));
diff --git a/includes/dhcp.h b/includes/dhcp.h
index d519821..75be1fb 100644
--- a/includes/dhcp.h
+++ b/includes/dhcp.h
@@ -76,6 +76,7 @@ struct dhcp_packet {
#define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
#define HTYPE_FDDI 8 /* FDDI... */
#define HTYPE_INFINIBAND 32 /* IP over Infiniband */
+#define HTYPE_PUREIP 35 /* Pure IP */
#define HTYPE_IPMP 255 /* IPMP - random hw address - there
* is no standard for this so we
* just steal a type */
--
2.39.2

View File

@ -0,0 +1,170 @@
From e67d1b6b4178f412084459c4cb7e54a8c0019bd2 Mon Sep 17 00:00:00 2001
From: Francis Dupont <fdupont@isc.org>
Date: Fri, 6 Nov 2020 10:46:09 +0100
Subject: [PATCH 2/4] Checkpoint: improved patch
---
common/bpf.c | 10 +++---
common/lpf.c | 89 +++++++++++++++++++++++++++++++++++-----------------
2 files changed, 65 insertions(+), 34 deletions(-)
diff --git a/common/bpf.c b/common/bpf.c
index 0c08574..30dcaa5 100644
--- a/common/bpf.c
+++ b/common/bpf.c
@@ -214,13 +214,13 @@ struct bpf_insn dhcp_bpf_pureip_filter [] = {
/* Make sure it's to the right port... */
BPF_STMT (BPF_LD + BPF_H + BPF_IND, 2),
- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 0, 1), /* patch */
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */
/* If we passed all the tests, ask for the whole packet. */
- BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
+ BPF_STMT(BPF_RET + BPF_K, (u_int)-1),
/* Otherwise, drop it. */
- BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_RET + BPF_K, 0),
};
int dhcp_bpf_pureip_filter_len =
@@ -278,11 +278,11 @@ struct bpf_insn dhcp_bpf_pureip_relay_filter [] = {
/* Make sure it's to the right port... */
BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 2, 0), /* patch */
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 2, 0), /* patch */
/* relay can have an alternative port... */
BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
- BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 37, 0, 1), /* patch */
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */
/* If we passed all the tests, ask for the whole packet. */
BPF_STMT (BPF_RET + BPF_K, (u_int)-1),
diff --git a/common/lpf.c b/common/lpf.c
index d8f34a4..75609f5 100644
--- a/common/lpf.c
+++ b/common/lpf.c
@@ -221,6 +221,9 @@ void if_register_receive (info)
lpf_tr_filter_setup (info);
else
#endif
+ if (info -> hw_address.hbuf [0] == HTYPE_PUREIP)
+ lpf_pureip_filter_setup (info);
+ else
lpf_gen_filter_setup (info);
if (!quiet_interface_discovery)
@@ -255,50 +258,78 @@ void if_deregister_receive (info)
static void lpf_gen_filter_setup (info)
struct interface_info *info;
{
- int pure_ip = info -> hw_address.hbuf [0] == HTYPE_PUREIP;
struct sock_fprog p;
memset(&p, 0, sizeof(p));
- /* Set up the bpf filter program structure and patch port(s).
- *
- * This is defined in bpf.c, XXX changes to filter program may
- * require changes to the insn number(s) used below! XXX
- */
+ /* Set up the bpf filter program structure. This is defined in
+ bpf.c */
+ p.len = dhcp_bpf_filter_len;
+ p.filter = dhcp_bpf_filter;
+
+ dhcp_bpf_filter [8].k = ntohs (local_port);
- if (pure_ip) {
- p.len = dhcp_bpf_pureip_filter_len;
- p.filter = dhcp_bpf_pureip_filter;
+ /* Patch the server port into the LPF program...
+ XXX changes to filter program may require changes
+ to the insn number(s) used below! XXX */
+#if defined(RELAY_PORT)
+ if (relay_port) {
+ /*
+ * If user defined relay UDP port, we need to filter
+ * also on the user UDP port.
+ */
+ p.len = dhcp_bpf_relay_filter_len;
+ p.filter = dhcp_bpf_relay_filter;
- /* patch port */
- dhcp_bpf_pureip_filter [6].k = ntohs (local_port);
- } else {
- p.len = dhcp_bpf_filter_len;
- p.filter = dhcp_bpf_filter;
+ dhcp_bpf_relay_filter [8].k = ntohs (local_port);
+ dhcp_bpf_relay_filter [10].k = ntohs (relay_port);
+ }
+#endif
- /* patch port */
- dhcp_bpf_filter [8].k = ntohs (local_port);
+ if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
+ sizeof p) < 0) {
+ if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+ errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
+ errno == EAFNOSUPPORT) {
+ log_error ("socket: %m - make sure");
+ log_error ("CONFIG_PACKET (Packet socket) %s",
+ "and CONFIG_FILTER");
+ log_error ("(Socket Filtering) are enabled %s",
+ "in your kernel");
+ log_fatal ("configuration!");
+ }
+ log_fatal ("Can't install packet filter program: %m");
}
+}
+
+static void lpf_pureip_gen_filter_setup (info)
+ struct interface_info *info;
+{
+ struct sock_fprog p;
+
+ memset(&p, 0, sizeof(p));
+
+ /* Set up the bpf filter program structure. This is defined in
+ bpf.c */
+ p.len = dhcp_bpf_pureip_filter_len;
+ p.filter = dhcp_bpf_pureip_filter;
+
+ dhcp_bpf_pureip_filter [6].k = ntohs (local_port);
+ /* Patch the server port into the LPF program...
+ XXX changes to filter program may require changes
+ to the insn number(s) used below! XXX */
#if defined(RELAY_PORT)
- /*
- * If user defined relay UDP port, we need to filter
- * also on the user UDP port.
- */
- if (relay_port && pure_ip) {
+ if (relay_port) {
+ /*
+ * If user defined relay UDP port, we need to filter
+ * also on the user UDP port.
+ */
p.len = dhcp_bpf_pureip_relay_filter_len;
p.filter = dhcp_bpf_pureip_relay_filter;
- /* patch ports */
dhcp_bpf_pureip_relay_filter [6].k = ntohs (local_port);
dhcp_bpf_pureip_relay_filter [8].k = ntohs (relay_port);
- } else if (relay_port) {
- p.len = dhcp_bpf_relay_filter_len;
- p.filter = dhcp_bpf_relay_filter;
-
- /* patch ports */
- dhcp_bpf_relay_filter [8].k = ntohs (local_port);
- dhcp_bpf_relay_filter [10].k = ntohs (relay_port);
}
#endif
--
2.39.2

View File

@ -0,0 +1,48 @@
From 58e0d3317795987b2f1ca788645196d0e3543f88 Mon Sep 17 00:00:00 2001
From: Adam Smith <zero1three@gmail.com>
Date: Tue, 23 Jan 2024 21:47:00 -0500
Subject: [PATCH 3/4] fix compilation errors
---
common/lpf.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/common/lpf.c b/common/lpf.c
index 75609f5..1561d71 100644
--- a/common/lpf.c
+++ b/common/lpf.c
@@ -195,6 +195,7 @@ static void lpf_tr_filter_setup (struct interface_info *);
#endif
static void lpf_gen_filter_setup (struct interface_info *);
+static void lpf_pureip_gen_filter_setup (struct interface_info *);
void if_register_receive (info)
struct interface_info *info;
@@ -215,14 +216,13 @@ void if_register_receive (info)
}
#endif
-
#if defined (HAVE_TR_SUPPORT)
if (info -> hw_address.hbuf [0] == HTYPE_IEEE802)
lpf_tr_filter_setup (info);
else
#endif
if (info -> hw_address.hbuf [0] == HTYPE_PUREIP)
- lpf_pureip_filter_setup (info);
+ lpf_pureip_gen_filter_setup (info);
else
lpf_gen_filter_setup (info);
@@ -349,6 +349,7 @@ static void lpf_pureip_gen_filter_setup (info)
}
}
+
#if defined (HAVE_TR_SUPPORT)
static void lpf_tr_filter_setup (info)
struct interface_info *info;
--
2.39.2

View File

@ -0,0 +1,29 @@
From fd96a11b31cd05aae450ec65fde0b5c6e0b718c2 Mon Sep 17 00:00:00 2001
From: Adam Smith <zero1three@gmail.com>
Date: Tue, 23 Jan 2024 22:35:54 -0500
Subject: [PATCH 4/4] add support for ARPHRD_NONE interface type
---
common/lpf.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/common/lpf.c b/common/lpf.c
index 1561d71..f7e84b1 100644
--- a/common/lpf.c
+++ b/common/lpf.c
@@ -643,6 +643,12 @@ get_hw_addr(const char *name, struct hardware *hw) {
hw->hlen = 1;
hw->hbuf[0] = HTYPE_PUREIP;
break;
+#endif
+#ifdef ARPHRD_NONE
+ case ARPHRD_NONE:
+ hw->hlen = 1;
+ hw->hbuf[0] = HTYPE_PUREIP;
+ break;
#endif
default:
log_fatal("Unsupported device type %ld for \"%s\"",
--
2.39.2