[PATCH v2] udhcp: add option to set CoS priority

Clément Péron peron.clem at gmail.com
Mon Jan 16 10:11:14 UTC 2023


Some ISP, like the French ISP Orange uses DHCP messages with
a CoS Priority of 6 otherwise they are not processed.

Add an option to allow setting this property.

Signed-off-by: Clément Péron <peron.clem at gmail.com>
---

Changes since v1:
- Use setsockopt_SOL_SOCKET_int()
- Introduce an helper udhcp_socket_prio()
- Move sk_prio in common.c

 networking/udhcp/Config.src  |  8 ++++++++
 networking/udhcp/common.c    | 15 +++++++++++++++
 networking/udhcp/common.h    |  3 +++
 networking/udhcp/d6_dhcpc.c  |  8 +++++++-
 networking/udhcp/d6_packet.c |  4 ++++
 networking/udhcp/dhcpc.c     | 10 +++++++++-
 networking/udhcp/packet.c    |  4 ++++
 7 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src
index 7ba7f48fc..49d5d7ef1 100644
--- a/networking/udhcp/Config.src
+++ b/networking/udhcp/Config.src
@@ -137,6 +137,14 @@ config UDHCP_DEBUG
 	Bigger values result in bigger code. Levels above 1
 	are very verbose and useful for debugging only.
 
+config FEATURE_UDHCPC_COS
+	bool "Enable '-y priority' option for udhcpc"
+	default n
+	depends on UDHCPC || UDHCPC6
+	help
+	At the cost of ~300 bytes, enables -y priority option.
+	This feature is typically not needed.
+
 config UDHCPC_SLACK_FOR_BUGGY_SERVERS
 	int "DHCP options slack buffer size"
 	default 80
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index ae818db05..d5ef54f0e 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -10,6 +10,8 @@
 unsigned dhcp_verbose;
 #endif
 
+IF_FEATURE_UDHCPC_COS(int sk_prio;)
+
 const uint8_t MAC_BCAST_ADDR[6] ALIGN2 = {
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff
 };
@@ -733,3 +735,16 @@ int FAST_FUNC sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip)
 		hexstrbuf + 7 * 4
 	);
 }
+
+#if defined CONFIG_FEATURE_UDHCPC_COS
+void FAST_FUNC udhcp_socket_prio(int fd)
+{
+	if (!sk_prio)
+		return;
+
+	log2("setting prio: %d", sk_prio);
+	if (setsockopt_SOL_SOCKET_int(fd, SO_PRIORITY, sk_prio)) {
+		bb_simple_error_msg("SO_PRIORITY setsockopt() failed");
+	}
+}
+#endif
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index 49a0b593d..4b276fe79 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -386,6 +386,9 @@ int arpping(uint32_t test_nip,
 /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */
 int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC;
 
+IF_FEATURE_UDHCPC_COS(extern int sk_prio;)
+IF_FEATURE_UDHCPC_COS(void udhcp_socket_prio(int fd) FAST_FUNC;)
+
 POP_SAVED_FUNCTION_VISIBILITY
 
 #endif
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index cdd06188e..59bdd34b3 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -129,6 +129,7 @@ static const char udhcpc6_longopts[] ALIGN1 =
 	)
 ///	IF_FEATURE_UDHCPC_ARPING("arping\0"	No_argument       "a")
 	IF_FEATURE_UDHCP_PORT("client-port\0"	Required_argument "P")
+	IF_FEATURE_UDHCPC_COS("cos\0"	Required_argument "y")
 	;
 #endif
 /* Must match getopt32 option string order */
@@ -1130,7 +1131,7 @@ static void client_background(void)
 //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:       "	[-p PIDFILE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-ldo] [-r IPv6] [-x OPT:VAL]... [-O OPT]..."
+//usage:       "	[-p PIDFILE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")""IF_FEATURE_UDHCPC_COS(" [-y PRIORITY]")" [-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")"
 //usage:     "\n	-p FILE		Create pidfile"
@@ -1153,6 +1154,9 @@ static void client_background(void)
 ////usage:	IF_FEATURE_UDHCPC_ARPING(
 ////usage:     "\n	-a		Use arping to validate offered address"
 ////usage:	)
+//usage:	IF_FEATURE_UDHCPC_COS(
+//usage:     "\n	-y PRIORITY	CoS value, default 0"
+//usage:	)
 //usage:     "\n	-l		Send 'information request' instead of 'solicit'"
 //usage:     "\n			(used for servers which do not assign IPv6 addresses)"
 //usage:     "\n	-r IPv6		Request this address ('no' to not request any IP)"
@@ -1214,6 +1218,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
 		USE_FOR_MMU("b")
 		///IF_FEATURE_UDHCPC_ARPING("a")
 		IF_FEATURE_UDHCP_PORT("P:")
+		IF_FEATURE_UDHCPC_COS("y:+")
 		"v"
 		"\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */
 		, udhcpc6_longopts
@@ -1223,6 +1228,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
 		, &list_O
 		, &list_x
 		IF_FEATURE_UDHCP_PORT(, &str_P)
+		IF_FEATURE_UDHCPC_COS(, &sk_prio)
 		IF_UDHCP_VERBOSE(, &dhcp_verbose)
 	);
 	requested_ipv6 = NULL;
diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c
index 142de9b43..424120c2c 100644
--- a/networking/udhcp/d6_packet.c
+++ b/networking/udhcp/d6_packet.c
@@ -68,6 +68,8 @@ int FAST_FUNC d6_send_raw_packet_from_client_data_ifindex(
 		goto ret_msg;
 	}
 
+	IF_FEATURE_UDHCPC_COS(udhcp_socket_prio(fd);)
+
 	memset(&dest_sll, 0, sizeof(dest_sll));
 	memset(&packet, 0, offsetof(struct ip6_udp_d6_packet, data));
 	packet.data = *d6_pkt; /* struct copy */
@@ -153,6 +155,8 @@ int FAST_FUNC d6_send_kernel_packet_from_client_data_ifindex(
 	}
 	setsockopt_reuseaddr(fd);
 
+	IF_FEATURE_UDHCPC_COS(udhcp_socket_prio(fd);)
+
 	memset(&sa, 0, sizeof(sa));
 	sa.sin6_family = AF_INET6;
 	sa.sin6_port = htons(source_port);
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index c757fb37c..60ae8ad70 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -77,6 +77,7 @@ static const char udhcpc_longopts[] ALIGN1 =
 	"broadcast\0"      No_argument       "B"
 	IF_FEATURE_UDHCPC_ARPING("arping\0"	Optional_argument "a")
 	IF_FEATURE_UDHCP_PORT("client-port\0"	Required_argument "P")
+	IF_FEATURE_UDHCPC_COS("cos\0"	Required_argument "y")
 	;
 #endif
 /* Must match getopt32 option string order */
@@ -1085,6 +1086,8 @@ static int udhcp_raw_socket(int ifindex)
 	}
 #endif
 
+	IF_FEATURE_UDHCPC_COS(udhcp_socket_prio(fd);)
+
 	if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) {
 		if (errno != ENOPROTOOPT)
 			log1s("can't set PACKET_AUXDATA on raw socket");
@@ -1162,7 +1165,7 @@ static void client_background(void)
 //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:       "	[-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n"
+//usage:       "	[-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")""IF_FEATURE_UDHCPC_COS(" [-y PRIORITY]")" [-s PROG] [-p PIDFILE]\n"
 //usage:       "	[-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..."
 //usage:#define udhcpc_full_usage "\n"
 //usage:     "\n	-i IFACE	Interface to use (default "CONFIG_UDHCPC_DEFAULT_INTERFACE")"
@@ -1186,6 +1189,9 @@ static void client_background(void)
 //usage:	IF_FEATURE_UDHCPC_ARPING(
 //usage:     "\n	-a[MSEC]	Validate offered address with ARP ping"
 //usage:	)
+//usage:	IF_FEATURE_UDHCPC_COS(
+//usage:     "\n	-y PRIORITY	CoS value, default 0"
+//usage:	)
 //usage:     "\n	-r IP		Request this IP address"
 //usage:     "\n	-o		Don't request any options (unless -O is given)"
 //usage:     "\n	-O OPT		Request option OPT from server (cumulative)"
@@ -1248,6 +1254,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
 		USE_FOR_MMU("b")
 		IF_FEATURE_UDHCPC_ARPING("a::")
 		IF_FEATURE_UDHCP_PORT("P:")
+		IF_FEATURE_UDHCPC_COS("y:+")
 		"v"
 		"\0" IF_UDHCP_VERBOSE("vv") /* -v is a counter */
 		, udhcpc_longopts
@@ -1260,6 +1267,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
 		, &list_x
 		IF_FEATURE_UDHCPC_ARPING(, &str_a)
 		IF_FEATURE_UDHCP_PORT(, &str_P)
+		IF_FEATURE_UDHCPC_COS(, &sk_prio)
 		IF_UDHCP_VERBOSE(, &dhcp_verbose)
 	);
 	if (opt & OPT_F) {
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index 529978189..9aaa51de9 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -121,6 +121,8 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
 		goto ret_msg;
 	}
 
+	IF_FEATURE_UDHCPC_COS(udhcp_socket_prio(fd);)
+
 	memset(&dest_sll, 0, sizeof(dest_sll));
 	memset(&packet, 0, offsetof(struct ip_udp_dhcp_packet, data));
 	packet.data = *dhcp_pkt; /* struct copy */
@@ -207,6 +209,8 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
 	}
 	setsockopt_reuseaddr(fd);
 
+	IF_FEATURE_UDHCPC_COS(udhcp_socket_prio(fd);)
+
 	/* If interface carrier goes down, unless we
 	 * bind socket to a particular netdev, the packet
 	 * can go out through another interface, eg. via
-- 
2.34.1



More information about the busybox mailing list