My French ISP (Orange) uses DHCP messages with a CoS Priority of 6, otherwise they are not processed. So in order to avoid using the set top box provided by him, you can use an OpenWRT router which comes with UDHCP (part of Busybox).
Here is a small patch to support this.
$(busybox)/networking/udhcp/dhcpc.c
In function udhcp_raw_socket(int ifindex), line 1086:
+ /* Set Kernel Priority to 6 */
+ int val = 6;
+ setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) {
if (errno != ENOPROTOOPT)
log1s("can't set PACKET_AUXDATA on raw socket");
}
$(busybox)/networking/udhcp/packet.c
In function udhcp_send_raw_packet, line 123:
+ /* Set Kernel Priority to 6 */
+ int val = 6;
+ setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
+ bb_info_msg("Packet priority set to %s", "6");
memset(&dest_sll, 0, sizeof(dest_sll));
memset(&packet, 0, offsetof(struct ip_udp_dhcp_packet, data));
packet.data = *dhcp_pkt; /* struct copy */
In function udhcp_send_kernel_packet, line 213:
+ /* Set Kernel Priority to 6 */
+ int val = 6;
+ setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
/* If interface carrier goes down, unless we
* bind socket to a particular netdev, the packet
* can go out through another interface, eg. via
* default route despite being bound to a specific
* source IP. As such, bind to device hard and fail
* otherwise. Sending renewal packets on foreign
* interfaces makes no sense.
*/
if (ifname) {
This article will mainly target people located in France, but who knows 🙂
Orange, a French ISP, provides FTTH with up to 2GB downling/600mbps uplink, but the usage (and rental…) of their set top box (aka Livebox) is mandatory.
As I’m using my own router (Ubiquiti EdgeRouter), the Livebox is useless to me, just taking some place and energy :-). The goal of this article is to explain how to remove it to use a router instead.
The Livebox 5 integrates an ONT. So in order to remove the LB5, I needed to find an external ONT. A friend gave me an “old” Huawei HG8010H, which is the one Orange used to provide with older Livebox versions.
The first thing to do is to gate the ONT accepted on the optical network, commonly know as O5 state (“operation state” – https://www.mdpi.com/2076-3417/8/10/1934/pdf). To reach this state, the ONT must authenticate itself on the carrier network. Orange used to rely on the SLID (subscriber line ID), but this is no longer used. It now only relies on the serial number of the ONT. It means that is necessary to change the Serial Number of the new ONT by the allowed one (the Livebox). Getting the “allowed” SN is easy: just go on the Livebox administration page:
Setting the same SN in the new ONT is possible if the ONT is not in the ISP locked mode. I will not cover how to unlock an Orange-provided HG8010 ONT, this can be found on the web with keyboard “restorehwmode.sh” !
Once the Serial Number is changed on the ONT to simulate the Livebox, the fiber link should come up in O5 mode::
Now that the fiber link is up – the router must be configured to access.
Orange is using multiple VLANs (internet, TV, SIP…). I will just be covering the Internet access as I’m not using TV nor phone.
For Internet, the VLAN 832 should be used, using DHCP and the “option 90”, which is used to authenticate the subscriber.
The tricky detail is the following: DHCP packets should be sent with a VLAN priority set to 6 ! Without doing that, device won’t be able to authenticate to the network.
Before configuring the router, several things will be needed, such as the Mac Address of the Livebox and the authentication data. This can be calculated using a JavaScript tool, using the username & password provided by Orange (famous “fti/xxxx”). I chose a different option, which consists in gathering those information from the Livebox.
Feel free to use this simple Python script to obtain the information and generate the configuration for your EdgeRouter:
Last problem: the VLAN Priority 6. The router uses ISC-DHCP as DHCP client, which relies on raw sockets. As such, it bypasses the “egress policy” you could define on the router.
The only solution is to patch & recompile the ISC-DHCP to hardcode the VLAN priority.
Patching and re-compiling ISC-DHCP
The easiest option is to use Docker! First of all, retrieve the package from Ubiquiti matching your router firmware version:
This archive includes all the package we need to recompile: edgeos-vyatta-dhcp.
Instanciate a Docker as follows:
docker run --rm -it debian:9.13 /bin/bash
Install necessary cross compilation toolchain:
apt-get update && apt-get install -y crossbuild-essential-mipsel vim
mkdir /data && cd /data
Copy the vyatta-dhcp3_4.1-ESV-R15-ubnt1+t5402460.dev.stretch.v2.0.9.24c30f9.tar.gz file to the /data in your docker:
For the version isc-dhclient-4.1-ESV-R15-P1, my patch file is:
--- a/common/discover.c
+++ b/common/discover.c
@@ -247,10 +247,6 @@ begin_iface_scan(struct iface_conf_list *ifaces) {
log_error("Error creating socket to list interfaces; %m");
return 0;
}
-
- /* Set Kernel Priority to 6 */
- int val = 6;
- setsockopt(ifaces->sock, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
memset(&lifnum, 0, sizeof(lifnum));
#ifdef ISC_PLATFORM_HAVELIFNUM
diff --git a/common/icmp.c b/common/icmp.c
index ca857e0..6f97f67 100644
--- a/common/icmp.c
+++ b/common/icmp.c
@@ -95,10 +95,6 @@ void icmp_startup (routep, handler)
return;
}
- /* Set Kernel Priority to 6 */
- int val = 6;
- setsockopt(icmp_state -> socket, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
-
#if defined (HAVE_SETFD)
if (fcntl (icmp_state -> socket, F_SETFD, 1) < 0)
log_error ("Can't set close-on-exec on icmp: %m");
diff --git a/common/lpf.c b/common/lpf.c
index 8111f38..fcf7db1 100644
--- a/common/lpf.c
+++ b/common/lpf.c
@@ -89,10 +89,6 @@ int if_register_lpf (info)
log_fatal ("Open a socket for LPF: %m");
}
- /* Set Kernel Priority to 6 */
- int val = 6;
- setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
-
memset (&ifr, 0, sizeof ifr);
strncpy (ifr.ifr_name, (const char *)info -> ifp, sizeof ifr.ifr_name);
ifr.ifr_name[IFNAMSIZ-1] = '\0';
@@ -499,10 +495,6 @@ get_hw_addr(const char *name, struct hardware *hw) {
log_fatal("Can't create socket for \"%s\": %m", name);
}
- /* Set Kernel Priority to 6 */
- int val = 6;
- setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
-
memset(&tmp, 0, sizeof(tmp));
strcpy(tmp.ifr_name, name);
if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
diff --git a/common/raw.c b/common/raw.c
index b588f1b..a15f8ee 100644
--- a/common/raw.c
+++ b/common/raw.c
@@ -66,10 +66,6 @@ void if_register_send (info)
if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
log_fatal ("Can't create dhcp socket: %m");
- /* Set Kernel Priority to 6 */
- int val = 6;
- setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
-
/* Set the BROADCAST option so that we can broadcast DHCP responses. */
flag = 1;
if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
diff --git a/common/socket.c b/common/socket.c
index 8f94a63..3fe3d09 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -189,10 +189,6 @@ if_register_socket(struct interface_info *info, int family,
log_fatal("Can't create dhcp socket: %m");
}
- /* Set Kernel Priority to 6 */
- int val = 6;
- setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
-
/* Set the REUSEADDR option so that we don't fail to start if
we're being restarted. */
flag = 1;
@@ -1178,10 +1174,6 @@ get_hw_addr(const char *name, struct hardware *hw) {
}
flag_check:
- /* Set Kernel Priority to 6 */
- int val = 6;
- setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
-
if (lifr.lifr_flags & (IFF_VIRTUAL|IFF_IPMP)) {
hw->hlen = sizeof (hw->hbuf);
srandom((long)gethrtime());
Finally, recompile DHCLIENT.
cd /data/edgeos-vyatta-dhcp
make -f debian/rules configure
CC=mipsel-linux-gnu-gcc CPP=mipsel-linux-gnu-cpp ./configure --host=mipsel-linux-gnu --cache-file=config.cache
make