[PATCH v3 RESEND] udhcpc(6): add -K option to set kernel packet priority
pacien
dzfkct.busyboxml at pacien.net
Mon Jan 1 23:37:23 UTC 2024
From: pacien <pacien.trangirard at pacien.net>
This adds a command line option (-K) to set the (kernel) packet
priority. The option is part of "FEATURE_UDHCPC_SK_PRIO".
This makes it straightforward to set some VLAN priority for DHCP
requests through an egress QoS map. Packet matching for firewall
or scheduler marking is otherwise broken due to the use of raw
packets.
(Such priority tag is a hard requirement for some ISPs, such as Orange
in France).
Enabling this feature costs 264 octets according to bloatcheck.
Co-authored-by: Clément Péron <peron.clem at gmail.com>
Signed-off-by: Pacien TRAN-GIRARD <pacien.trangirard at pacien.net>
---
networking/udhcp/Config.src | 10 ++++++++++
networking/udhcp/common.h | 6 ++++--
networking/udhcp/d6_common.h | 2 ++
networking/udhcp/d6_dhcpc.c | 26 +++++++++++++++++++-------
networking/udhcp/d6_packet.c | 21 +++++++++++++++++++--
networking/udhcp/dhcpc.c | 29 ++++++++++++++++++++---------
networking/udhcp/dhcpc.h | 1 +
networking/udhcp/dhcpd.c | 6 ++++--
networking/udhcp/packet.c | 21 +++++++++++++++++++--
9 files changed, 98 insertions(+), 24 deletions(-)
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src
index 7ba7f48fc..731cf12fa 100644
--- a/networking/udhcp/Config.src
+++ b/networking/udhcp/Config.src
@@ -176,3 +176,13 @@ config FEATURE_UDHCP_8021Q
help
If selected, both client and server will support passing of VLAN
ID and priority via options 132 and 133 as per 802.1Q.
+
+config FEATURE_UDHCPC_SK_PRIO
+ bool "Enable '-K' option for udhcpc"
+ default y
+ depends on UDHCPC || UDHCPC6
+ help
+ If selected, enables -K option to set the kernel priority of DHCP
+ packets. Useful together with some egress QoS mapping to send
+ requests with a specific VLAN priority tag, as required by some
+ ISPs.
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index 49a0b593d..30ee68375 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -359,12 +359,14 @@ int udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) FAST_FUNC;
int udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_nip, int source_port,
uint32_t dest_nip, int dest_port, const uint8_t *dest_arp,
- int ifindex) FAST_FUNC;
+ int ifindex
+ IF_FEATURE_UDHCPC_SK_PRIO(, int sk_prio)) FAST_FUNC;
int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_nip, int source_port,
uint32_t dest_nip, int dest_port,
- const char *ifname) FAST_FUNC;
+ const char *ifname
+ IF_FEATURE_UDHCPC_SK_PRIO(, int sk_prio)) FAST_FUNC;
void udhcp_sp_setup(void) FAST_FUNC;
void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC;
diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h
index 3cbfbb89e..05a5dc2b4 100644
--- a/networking/udhcp/d6_common.h
+++ b/networking/udhcp/d6_common.h
@@ -180,12 +180,14 @@ int FAST_FUNC d6_send_raw_packet_from_client_data_ifindex(
struct d6_packet *d6_pkt, unsigned d6_pkt_size,
struct in6_addr *src_ipv6, int source_port,
struct in6_addr *dst_ipv6, int dest_port, const uint8_t *dest_arp
+ IF_FEATURE_UDHCPC_SK_PRIO(, int sk_prio)
);
int FAST_FUNC d6_send_kernel_packet_from_client_data_ifindex(
struct d6_packet *d6_pkt, unsigned d6_pkt_size,
struct in6_addr *src_ipv6, int source_port,
struct in6_addr *dst_ipv6, int dest_port
+ IF_FEATURE_UDHCPC_SK_PRIO(, int sk_prio)
);
#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index cdd06188e..173aa2914 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -127,6 +127,7 @@ static const char udhcpc6_longopts[] ALIGN1 =
USE_FOR_MMU(
"background\0" No_argument "b"
)
+ IF_FEATURE_UDHCPC_SK_PRIO("sk-priority\0" Required_argument "K")
/// IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a")
IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")
;
@@ -152,12 +153,14 @@ enum {
OPT_d = 1 << 16,
/* The rest has variable bit positions, need to be clever */
OPTBIT_d = 16,
- USE_FOR_MMU( OPTBIT_b,)
- ///IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
- IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
- USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,)
- ///IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,)
- IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)
+ USE_FOR_MMU( OPTBIT_b,)
+ IF_FEATURE_UDHCPC_SK_PRIO(OPTBIT_K,)
+ ///IF_FEATURE_UDHCPC_ARPING( OPTBIT_a,)
+ IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
+ USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,)
+ IF_FEATURE_UDHCPC_SK_PRIO(OPT_K = 1 << OPTBIT_K,)
+ ///IF_FEATURE_UDHCPC_ARPING( OPT_a = 1 << OPTBIT_a,)
+ IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)
};
#if ENABLE_FEATURE_UDHCPC6_RFC4704
@@ -561,6 +564,7 @@ static int d6_mcast_from_client_data_ifindex(struct d6_packet *packet, uint8_t *
packet, (end - (uint8_t*) packet),
/*src*/ &client6_data.ll_ip6, CLIENT_PORT6,
/*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_DHCP6MCAST_ADDR
+ IF_FEATURE_UDHCPC_SK_PRIO(, client_data.sk_prio)
);
}
@@ -866,6 +870,7 @@ static NOINLINE int send_d6_renew(struct in6_addr *server_ipv6, struct in6_addr
&packet, (opt_ptr - (uint8_t*) &packet),
our_cur_ipv6, CLIENT_PORT6,
server_ipv6, SERVER_PORT6
+ IF_FEATURE_UDHCPC_SK_PRIO(, client_data.sk_prio)
);
return d6_mcast_from_client_data_ifindex(&packet, opt_ptr);
}
@@ -899,6 +904,7 @@ int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cur_ipv6)
&packet, (opt_ptr - (uint8_t*) &packet),
our_cur_ipv6, CLIENT_PORT6,
server_ipv6, SERVER_PORT6
+ IF_FEATURE_UDHCPC_SK_PRIO(, client_data.sk_prio)
);
}
@@ -1129,7 +1135,7 @@ static void client_background(void)
//usage:# define IF_UDHCP_VERBOSE(...)
//usage:#endif
//usage:#define udhcpc6_trivial_usage
-//usage: "[-fbq"IF_UDHCP_VERBOSE("v")"R] [-t N] [-T SEC] [-A SEC|-n] [-i IFACE] [-s PROG]\n"
+//usage: "[-fbq"IF_UDHCP_VERBOSE("v")"R]"IF_FEATURE_UDHCPC_SK_PRIO(" [-K PRIO]")" [-t N] [-T SEC] [-A SEC|-n] [-i IFACE] [-s PROG]\n"
//usage: " [-p PIDFILE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-ldo] [-r IPv6] [-x OPT:VAL]... [-O OPT]..."
//usage:#define udhcpc6_full_usage "\n"
//usage: "\n -i IFACE Interface to use (default "CONFIG_UDHCPC_DEFAULT_INTERFACE")"
@@ -1150,6 +1156,9 @@ static void client_background(void)
//usage: IF_FEATURE_UDHCP_PORT(
//usage: "\n -P PORT Use PORT (default 546)"
//usage: )
+//usage: IF_FEATURE_UDHCPC_SK_PRIO(
+//usage: "\n -K PRIO Set kernel packet priority (default 0)"
+//usage: )
////usage: IF_FEATURE_UDHCPC_ARPING(
////usage: "\n -a Use arping to validate offered address"
////usage: )
@@ -1199,6 +1208,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
/* Default options */
IF_FEATURE_UDHCP_PORT(SERVER_PORT6 = 547;)
IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;)
+ IF_FEATURE_UDHCPC_SK_PRIO(client_data.sk_prio = 0;)
client_data.interface = CONFIG_UDHCPC_DEFAULT_INTERFACE;
client_data.script = CONFIG_UDHCPC6_DEFAULT_SCRIPT;
client_data.sockfd = -1;
@@ -1212,6 +1222,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
/* O,x: list; -T,-t,-A take numeric param */
"i:np:qRr:s:T:+t:+SA:+O:*ox:*fld"
USE_FOR_MMU("b")
+ IF_FEATURE_UDHCPC_SK_PRIO("K:+")
///IF_FEATURE_UDHCPC_ARPING("a")
IF_FEATURE_UDHCP_PORT("P:")
"v"
@@ -1222,6 +1233,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
, &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */
, &list_O
, &list_x
+ IF_FEATURE_UDHCPC_SK_PRIO(, &client_data.sk_prio)
IF_FEATURE_UDHCP_PORT(, &str_P)
IF_UDHCP_VERBOSE(, &dhcp_verbose)
);
diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c
index 142de9b43..501497154 100644
--- a/networking/udhcp/d6_packet.c
+++ b/networking/udhcp/d6_packet.c
@@ -54,7 +54,8 @@ int FAST_FUNC d6_recv_kernel_packet(struct in6_addr *peer_ipv6 UNUSED_PARAM,
int FAST_FUNC d6_send_raw_packet_from_client_data_ifindex(
struct d6_packet *d6_pkt, unsigned d6_pkt_size,
struct in6_addr *src_ipv6, int source_port,
- struct in6_addr *dst_ipv6, int dest_port, const uint8_t *dest_arp)
+ struct in6_addr *dst_ipv6, int dest_port, const uint8_t *dest_arp
+ IF_FEATURE_UDHCPC_SK_PRIO(, int sk_prio))
{
struct sockaddr_ll dest_sll;
struct ip6_udp_d6_packet packet;
@@ -68,6 +69,13 @@ int FAST_FUNC d6_send_raw_packet_from_client_data_ifindex(
goto ret_msg;
}
+#if ENABLE_FEATURE_UDHCPC_SK_PRIO
+ if (setsockopt_SOL_SOCKET_int(fd, SO_PRIORITY, sk_prio) < 0) {
+ msg = "setsockopt(%s)";
+ goto ret_close;
+ }
+#endif
+
memset(&dest_sll, 0, sizeof(dest_sll));
memset(&packet, 0, offsetof(struct ip6_udp_d6_packet, data));
packet.data = *d6_pkt; /* struct copy */
@@ -139,7 +147,8 @@ int FAST_FUNC d6_send_raw_packet_from_client_data_ifindex(
int FAST_FUNC d6_send_kernel_packet_from_client_data_ifindex(
struct d6_packet *d6_pkt, unsigned d6_pkt_size,
struct in6_addr *src_ipv6, int source_port,
- struct in6_addr *dst_ipv6, int dest_port)
+ struct in6_addr *dst_ipv6, int dest_port
+ IF_FEATURE_UDHCPC_SK_PRIO(, int sk_prio))
{
struct sockaddr_in6 sa;
int fd;
@@ -151,6 +160,14 @@ int FAST_FUNC d6_send_kernel_packet_from_client_data_ifindex(
msg = "socket(%s)";
goto ret_msg;
}
+
+#if ENABLE_FEATURE_UDHCPC_SK_PRIO
+ if (setsockopt_SOL_SOCKET_int(fd, SO_PRIORITY, sk_prio) < 0) {
+ msg = "setsockopt(%s)";
+ goto ret_close;
+ }
+#endif
+
setsockopt_reuseaddr(fd);
memset(&sa, 0, sizeof(sa));
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index c757fb37c..8108f6856 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -75,6 +75,7 @@ static const char udhcpc_longopts[] ALIGN1 =
"background\0" No_argument "b"
)
"broadcast\0" No_argument "B"
+ IF_FEATURE_UDHCPC_SK_PRIO("sk-priority\0" Required_argument "K")
IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a")
IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")
;
@@ -102,12 +103,14 @@ enum {
OPT_B = 1 << 18,
/* The rest has variable bit positions, need to be clever */
OPTBIT_B = 18,
- USE_FOR_MMU( OPTBIT_b,)
- IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,)
- IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
- USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,)
- IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,)
- IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)
+ USE_FOR_MMU( OPTBIT_b,)
+ IF_FEATURE_UDHCPC_SK_PRIO(OPTBIT_K,)
+ IF_FEATURE_UDHCPC_ARPING( OPTBIT_a,)
+ IF_FEATURE_UDHCP_PORT( OPTBIT_P,)
+ USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,)
+ IF_FEATURE_UDHCPC_SK_PRIO(OPT_K = 1 << OPTBIT_K,)
+ IF_FEATURE_UDHCPC_ARPING( OPT_a = 1 << OPTBIT_a,)
+ IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,)
};
@@ -704,7 +707,8 @@ static int raw_bcast_from_client_data_ifindex(struct dhcp_packet *packet, uint32
return udhcp_send_raw_packet(packet,
/*src*/ src_nip, CLIENT_PORT,
/*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
- client_data.ifindex);
+ client_data.ifindex
+ IF_FEATURE_UDHCPC_SK_PRIO(, client_data.sk_prio));
}
static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server)
@@ -713,7 +717,8 @@ static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t
return udhcp_send_kernel_packet(packet,
ciaddr, CLIENT_PORT,
server, SERVER_PORT,
- client_data.interface);
+ client_data.interface
+ IF_FEATURE_UDHCPC_SK_PRIO(, client_data.sk_prio));
return raw_bcast_from_client_data_ifindex(packet, ciaddr);
}
@@ -1161,7 +1166,7 @@ static void client_background(void)
//usage:# define IF_UDHCP_VERBOSE(...)
//usage:#endif
//usage:#define udhcpc_trivial_usage
-//usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC|-n]\n"
+//usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_SK_PRIO(" [-K PRIO]")IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC|-n]\n"
//usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n"
//usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..."
//usage:#define udhcpc_full_usage "\n"
@@ -1183,6 +1188,9 @@ static void client_background(void)
//usage: "\n -R Release IP on exit"
//usage: "\n -f Run in foreground"
//usage: "\n -S Log to syslog too"
+//usage: IF_FEATURE_UDHCPC_SK_PRIO(
+//usage: "\n -K PRIO Set kernel packet priority (default 0)"
+//usage: )
//usage: IF_FEATURE_UDHCPC_ARPING(
//usage: "\n -a[MSEC] Validate offered address with ARP ping"
//usage: )
@@ -1232,6 +1240,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
/* Default options */
IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
+ IF_FEATURE_UDHCPC_SK_PRIO(client_data.sk_prio = 0;)
client_data.interface = CONFIG_UDHCPC_DEFAULT_INTERFACE;
client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
client_data.sockfd = -1;
@@ -1246,6 +1255,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
/* O,x: list; -T,-t,-A take numeric param */
"CV:F:i:np:qRr:s:T:+t:+SA:+O:*ox:*fB"
USE_FOR_MMU("b")
+ IF_FEATURE_UDHCPC_SK_PRIO("K:+")
IF_FEATURE_UDHCPC_ARPING("a::")
IF_FEATURE_UDHCP_PORT("P:")
"v"
@@ -1258,6 +1268,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
, &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */
, &list_O
, &list_x
+ IF_FEATURE_UDHCPC_SK_PRIO(, &client_data.sk_prio)
IF_FEATURE_UDHCPC_ARPING(, &str_a)
IF_FEATURE_UDHCP_PORT(, &str_P)
IF_UDHCP_VERBOSE(, &dhcp_verbose)
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index 19b054b32..733491953 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -9,6 +9,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
struct client_data_t {
uint8_t client_mac[6]; /* Our mac address */
+ IF_FEATURE_UDHCPC_SK_PRIO(int sk_prio;)
IF_FEATURE_UDHCP_PORT(uint16_t port;)
int ifindex; /* Index number of the interface to use */
uint32_t xid;
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 66750e2e6..814b791b0 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -603,7 +603,8 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc
udhcp_send_raw_packet(dhcp_pkt,
/*src*/ server_data.server_nip, SERVER_PORT,
/*dst*/ ciaddr, CLIENT_PORT, chaddr,
- server_data.ifindex);
+ server_data.ifindex
+ IF_FEATURE_UDHCPC_SK_PRIO(, 0));
}
/* Send a packet to gateway_nip using the kernel ip stack */
@@ -618,7 +619,8 @@ static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt)
* even those which are clients' requests and would normally
* (i.e. without relay) use CLIENT_PORT. See RFC 1542.
*/
- server_data.interface);
+ server_data.interface
+ IF_FEATURE_UDHCPC_SK_PRIO(, 0));
}
static void send_packet(struct dhcp_packet *dhcp_pkt, int force_broadcast)
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index 529978189..9cd2beafe 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -106,7 +106,8 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd)
int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_nip, int source_port,
uint32_t dest_nip, int dest_port, const uint8_t *dest_arp,
- int ifindex)
+ int ifindex
+ IF_FEATURE_UDHCPC_SK_PRIO(, int sk_prio))
{
struct sockaddr_ll dest_sll;
struct ip_udp_dhcp_packet packet;
@@ -121,6 +122,13 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
goto ret_msg;
}
+#if ENABLE_FEATURE_UDHCPC_SK_PRIO
+ if (setsockopt_SOL_SOCKET_int(fd, SO_PRIORITY, sk_prio) < 0) {
+ msg = "setsockopt(%s)";
+ goto ret_close;
+ }
+#endif
+
memset(&dest_sll, 0, sizeof(dest_sll));
memset(&packet, 0, offsetof(struct ip_udp_dhcp_packet, data));
packet.data = *dhcp_pkt; /* struct copy */
@@ -192,7 +200,8 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_nip, int source_port,
uint32_t dest_nip, int dest_port,
- const char *ifname)
+ const char *ifname
+ IF_FEATURE_UDHCPC_SK_PRIO(, int sk_prio))
{
struct sockaddr_in sa;
unsigned padding;
@@ -205,6 +214,14 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
msg = "socket(%s)";
goto ret_msg;
}
+
+#if ENABLE_FEATURE_UDHCPC_SK_PRIO
+ if (setsockopt_SOL_SOCKET_int(fd, SO_PRIORITY, sk_prio) < 0) {
+ msg = "setsockopt(%s)";
+ goto ret_close;
+ }
+#endif
+
setsockopt_reuseaddr(fd);
/* If interface carrier goes down, unless we
--
2.42.0
More information about the busybox
mailing list