diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e3cabf6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,103 @@ +# These are some examples of commonly ignored file patterns. +# You should customize this list as applicable to your project. +# Learn more about .gitignore: +# https://www.atlassian.com/git/tutorials/saving-changes/gitignore + +# Node artifact files +node_modules/ +dist/ + +# Compiled Java class files +*.class + +# Compiled Python bytecode +*.py[cod] + +# Log files +*.log + +# Package files +*.jar + +# Maven +target/ +dist/ + +# JetBrains IDE +.idea/ + +# VSCode +.vscode/ + +# vi swp +*.swp + +# Unit test reports +TEST*.xml + +# Generated by MacOS +.DS_Store + +# Generated by Windows +Thumbs.db + +# Applications +*.app +*.exe +*.war + +# Large media files +*.mp4 +*.tiff +*.avi +*.flv +*.mov +*.wmv + + + +# Terraform +## Local .terraform directories +**/.terraform/* +.terraform/ + +## .tfstate files +_TFSTAT/* +_TFSTATE/* +*.tfstate +*.tfstate.* +.terraform.lock.* + +## Crash log files +crash.log +crash.*.log + +## Exclude all .tfvars files, which are likely to contain sentitive data, such as +## password, private keys, and other secrets. These should not be part of version +## control as they are data points which are potentially sensitive and subject +## to change depending on the environment. +#*.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +## Include override files you do wish to add to version control using negated pattern +## !example_override.tf + +## Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +## example: *tfplan* + +## Ignore CLI configuration files +.terraformrc +terraform.rc + +# remove anonymization script +#.anonymize.sh +#.security.sh +#.git-anonymize.sh +.git-security.sh + diff --git a/index.html b/index.html index 7ef7667..e37a2dc 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@ |_| |_|_.__/ \__,_/_/\_\.org -Use your own router with Orange (French ISP) +Bring your own router with Orange (French ISP) more to come later... diff --git a/orange/dhcp-orange.html b/orange/dhcp-orange.html deleted file mode 100644 index 350d6b1..0000000 --- a/orange/dhcp-orange.html +++ /dev/null @@ -1,5087 +0,0 @@ - - - - dhcp-orange - - - - - - - - - - - - - - - - - - - - - - - - -
dhcp-orange

Use your own router with Orange ISP

#orange #dhcp #mikrotik #systemd-networkd
-dhcp-orange Version 20230719

This document describe how-to configure DHCP clients for ISP Orange in France. This could be used to remove the Livebox and prefer your own router…

Requirements

You must already have a working ONT/ONU registered on Orange fiber infrastructure. ONT/ONU are registering on Orange infrastructure with serial number.
-For informations, Orange use serial_number and vendor_id to allow a ONT/ONU to register.
-To configure properly your ONU/ONT, check dedicated topics and forums...

2023 evolutions

https://lafibre.info/remplacer-livebox/durcissement-du-controle-de-loption-9011-et-de-la-conformite-protocolaire/
-Since December 2022, the following DHCP options are MANDATORY !

ipv4

    -
  • user-class [77] : "FSVDSL_livebox.Internet.softathome.Livebox6" or "2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
  • -
  • vendor-class-identifier [60] : "sagem" or "0x736167656d"
  • -
  • rfc3118-authentication [90] : "authentication string (00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0Dxxx)"
  • -
  • dhcp-client-identifier [61] : "01:<mac_addr>" or "01<mac_addr>" or "0x01<mac_addr>"
  • -

ipv6

    -
  • user-class [15] : "002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
  • -
  • class-identifier [16] : "00:00:04:0e:00:05:73:61:67:65:6d" or "0x0000040e0005736167656d"
  • -
  • authentication [11] : "authentication string (00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0Dxxx)"
  • -
  • client DUID [1] : "00:03:00:01:<mac_addr>" or "00030001<mac_addr>" or "0x00030001<mac_addr>"
  • -

notes

    -
  • All DHCP requests must be done with COS6 (DSCP6 recommended too).
  • -
  • When you switch hardware (new router / ONU / ONT) you have to wait a few minutes with DISCONNECTED fiber link. DHCP IAID are dynamically generated by hardware equipments and Orange is waiting for a single IAID per client. To force expiration, the only way is to disconnect fiber 15-30 minutes and wait… The issue is that you will NOT get DHCPv6 prefix (NoPrefixAvail) from Orange.
  • -
  • note authentication : ipv4 and ipv6 strings MUST be equals
  • -
  • note user-class : user-class (ipv4:77 / ipv6:15) must match ipv4 and ipv6 (with different formats)
  • -

string2hex(FSVDSL_livebox.Internet.softathome.Livebox4) -> "46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7834"
-user-class string = "2b" + string2hex() ; ipv6 string = "00" + "ipv4 string"

WARNING : take care of case (livebox vs Livebox)

[ipv4:77] : "FSVDSL_livebox.Internet.softathome.Livebox4" or "0x2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7834"
-[ipv6:15] : "002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7834"
-
-[ipv4:77] : "FSVDSL_livebox.Internet.softathome.Livebox5" or "0x2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7835"
-[ipv6:15] : "002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7835"
-
-[ipv4:77] : "FSVDSL_livebox.Internet.softathome.Livebox6" or "0x2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
-[ipv6:15] : "002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
-

WARNING : if dhcp client use raw or not, final (and true) string to have in tcpdump sniff should be (for LB6) :

[ipv4:77] : "4d2c2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
-[ipv6:15] : "000f002d002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
-
    -
  • note vendor-opts : vendor-opts (or vendor_opts for vendor specific informations, IS NOT REQUIRED) [17] : "00:00:05:58:00:06:00:0e:49:50:56:36:5f:52:45:51:55:45:53:54:45:44" or "0x000005580006000e495056365f524551554553544544”, entreprise id "Orange" 4 octets 00000558 + 2 octets code 0006 + 14 octets data: 495056365f524551554553544544 ("IPV6_REQUESTED")
  • -
  • note systemd-networkd : each string must converted from "aa:bb:cc:dd:ee:....." to xaaxbbxbbxccxddxeex...." (replace ":" with "x") echo "aa:bb:cc:dd:ee" | sed 's/^/\\\x/ ; s/:/\\\x/g'
  • -

systemd-network sample config :

[DHCPv4]
-ClientIdentifier=mac
-VendorClassIdentifier=sagem
-UserClass=FSVDSL_livebox.Internet.softathome.Livebox6
-SendOption=90:string:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1A\x09\x00\x00\x05\x58\x01\x03\x41\x01\x0D\x66\x74\x69...
-[DHCPv6]
-DUIDType=link-layer
-# UserClass and SendOption=15:string: are equivalent
-UserClass=FSVDSL_livebox.Internet.softathome.Livebox6
-#UserClass=\x00\x2b\x46\x53\x56\x44\x53\x4c\x5f\x6c\x69\x76\x65\x62\x6f\x78\x2e\x49\x6e\x74\x65\x72\x6e\x65\x74\x2e\x73\x6f\x66\x74\x61\x74\x68\x6f\x6d\x65\x2e\x4c\x69\x76\x65\x62\x6f\x78\x36
-#SendOption=15:string:\x00\x2b\x46\x53\x56\x44\x53\x4c\x5f\x6c\x69\x76\x65\x62\x6f\x78\x2e\x49\x6e\x74\x65\x72\x6e\x65\x74\x2e\x73\x6f\x66\x74\x61\x74\x68\x6f\x6d\x65\x2e\x4c\x69\x76\x65\x62\x6f\x78\x36
-SendOption=11:string:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1A\x09\x00\x00\x05\x58\x01\x03\x41\x01\x0D\x66\x74\x69...
-SendOption=16:string:\x00\x00\x04\x0e\x00\x05\x73\x61\x67\x65\x6d
-

Option Request Option

The DHCPv6 ORO (Option Request Option, code 6), the following options are required :
-Option: Option Request (6) - Length: 8 - Value: 000b001100170018
-Requested Option code: Authentication (11)
-Requested Option code: Vendor-specific Information (17)
-Requested Option code: DNS recursive name server (23)
-Requested Option code: Domain Search List (24)

But, for the RFC8415 (https://datatracker.ietf.org/doc/html/rfc8415#section-21.7), option 11 (Authentication) is forbidden.
-For Orange, it is NOT mandatory to include option 11 in SOLLICIT/REQUEST requests. You can only keep options 17,23,24.

Authentication

note : You could also use https://jsfiddle.net/kgersen/3mnsc6wy/

shell script to generate authentication string :

#!/bin/bash
-# You could also use https://jsfiddle.net/kgersen/3mnsc6wy/
-# Version 20221214
-
-[ -z "$2" ] && echo "usage : $0 '<fti/login>' '<passwd>'" && exit 1
-
-login="$1" ; pass="$2"
-
-tohex() {
-      for h in $(echo $1 | sed "s/\(.\)/\1 /g"); do printf %02x \'$h; done
-}
-
-addsep() {
-      echo $(echo $1 | sed "s/\(.\)\(.\)/:\1\2/g")
-}
-
-r=$(dd if=/dev/urandom bs=1k count=1 2>&1 | md5sum | cut -c1-16)
-id=${r:0:1}
-h=3C12$(tohex ${r})0313$(tohex ${id})$(echo -n ${id}${pass}${r} | md5sum | cut -c1-32)
-str=$(addsep $(tohex ${login})${h})
-
-echo "# dhclient"
-echo "## ipv4"
-echo "send rfc3118-authentication 00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0D${str};"
-echo "## ipv6"
-echo "send dhcp6.auth 00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0D${str};"
-
-echo
-echo "# systemd-networkd"
-echo "## [DHCPv4]"
-str2=`echo "00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0D${str}" | sed 's/^/\\\x/ ; s/:/\\\x/g'`
-echo "SendOption=90:string:${str2}"
-echo "## [DHCPv6]"
-echo "SendOption=11:string:${str2}"
-
-echo
-echo "# mikrotik routeros"
-echo "## DHCPv4"
-echo "/ip dhcp-client option"
-str2=`echo "00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0D${str}" | sed 's/://g'`
-echo "add code=90 name=authsend value=0x${str2}"
-echo "## DHCPv6"
-echo "/ipv6 dhcp-client option"
-echo "add code=11 name=authsend value=0x${str2}"
-

COS 6

DHCP packets MUST be flagged COS/PCP and DSCP class-of-service
-However, DSCP is not mandatory but recommended.

DHCPv4 clients use RAW SOCKETS for DISCOVER/REQUEST (init) requests and BSD/UDP SOCKETS for RENEW requests.
-In consequence, you CANNOT use netfilter mangle rules to change COS/PCP and DSCP. You MUST use L2 filtering.

On Linux L2 filtering can be done with tc (traffic-control) tool. On Mikrotik router there switch rules or bridge filters.

linux tc

#!/bin/sh
-iface="orange1"
-tc_qos="0:6"
-vlan="832"
-physiface="wan1"
-mac_addr="<livebox_mac>"
-ip link add link $physiface name $iface type vlan id $vlan
-ip link set dev $iface address $mac_addr
-ip link set $iface up
-tc qdisc del dev $iface root ; tc filter del dev $iface
-tc qdisc replace dev $iface root handle 1: prio
-tc filter add dev $iface parent 1: prio 1 u32 match ip protocol 17 ff match ip dport 67 ffff action skbedit priority $tc_qos # dhcpv4
-tc filter add dev $iface parent 1: prio 2 protocol ipv6 u32 match ip6 protocol 17 ff match ip6 dport 547 ffff action skbedit priority $tc_qos # dhcpv6
-# the following is not mandatory, but recommended
-tc filter add dev $iface parent 1: prio 3 protocol 0x806 u32 match u32 0 0 action skbedit priority $tc_cos # arp
-tc filter add dev $iface parent 1: prio 4 protocol ipv6 u32 match ip6 dst fe00::/7 match ip6 protocol 58 ff action skbedit priority $tc_cos # icmpv6_dst (fe00::/7 = fe80::/10 + ff02::/16)
-# for information
-#tc filter add dev $iface parent 1: prio 4 protocol ipv6 u32 match ip6 protocol 58 ff action skbedit priority $tc_cos # icmpv6
-#tc filter add dev $iface parent 1: prio 5 protocol ip u32 match ip protocol 1 ff action skbedit priority $tc_cos # icmpv4 - SHOULD NOT BE USED !
-

DSCP (optional)

https://lafibre.info/remplacer-livebox/durcissement-du-controle-de-loption-9011-et-de-la-conformite-protocolaire/324/
-https://linuxreviews.org/Type_of_Service_(ToS)_and_DSCP_Values
-This version of tc script change COS and DSCP to 6, it should work but it has NOT been tested and work in progress.
-note DSCP : CS6 = 48 (dec) = 0xc0 (TOS-hex)

script based on tc :

#!/bin/sh
-iface="orange1"
-tc_cos="0:6"
-tc_tos="0xc0"
-tc_retain="0xfc"
-vlan="832"
-physiface="wan1"
-mac_addr="<livebox_mac>"
-ip link add link $physiface name $iface type vlan id $vlan
-ip link set dev $iface address $mac_addr
-ip link set $iface up
-tc qdisc del dev $iface root ; tc filter del dev $iface
-tc qdisc replace dev $iface root handle 1: prio
-tc filter add dev $iface parent 1: prio 1 protocol ip u32 match ip ihl 5 0xf match u16 0x0000 0x1fff at 6 match ip protocol 17 0xff match ip sport 68 0xffff match ip dport 67 0xffff action skbedit priority $tc_cos pipe action pedit pedit munge ip tos set $tc_tos retain $tc_retain pipe action csum ip4h # dhcpv4_DSCP
-tc filter add dev $iface parent 1: prio 2 protocol ipv6 u32 match ip6 protocol 17 0xff match ip6 sport 546 0xffff match ip6 dport 547 0xffff action skbedit priority $tc_cos pipe action pedit pedit munge ip6 tos set $tc_tos retain $tc_retain # dhcpv6_DSCP
-# the following is not mandatory, but recommended
-tc filter add dev $iface parent 1: prio 3 protocol arp u32 match u8 0 0 action skbedit priority $tc_cos # arp
-tc filter add dev $iface parent 1: prio 4 protocol ipv6 u32 match ip6 dst fe00::/7 match ip6 protocol 58 0xff action skbedit priority 0:6 pipe action pedit ex munge ip6 traffic_class set $tc_tos retain $tc_retain # icmpv6_dst_DSCP (fe00::/7 = fe80::/10 + ff02::/16)
-# for information - no dscp
-#tc filter add dev $iface parent 1: prio 3 protocol ipv6 u32 match ip6 protocol 17 0xff match ip6 sport 546 0xffff match ip6 dport 547 0xffff action skbedit priority $tc_cos # dhcpv6 
-#tc filter add dev $iface parent 1: prio 4 protocol ipv6 u32 match ip6 dst fe00::/7 match ip6 protocol 58 0xff action skbedit priority $tc_cos # icmpv6 dst (fe00::/7 = fe80::/10 + ff02::/16)
-

nftables

https://lafibre.info/remplacer-livebox/durcissement-du-controle-de-loption-9011-et-de-la-conformite-protocolaire/324/
-The following change DSCP and COS for ipv6 NS/NA/RS packets.
-note : nftables is NOT able to modify ipv4 DHCP packets, because they are using RAW sockets.

    -
  • original version (prefer next/simpler/better version) :
  • -
iface = orange1.832
-table inet firewall {
-	chain prio_orange {
-		meta nfproto ipv4 
-			meta priority set 0:0 
-			ip dscp set cs0
-
-    	meta nfproto ipv6 
-    		meta priority set 0:0 
-    		ip6 dscp set cs0
-    	ip6 daddr { fe80::/10, ff02::/16 } 
-    		icmpv6 type {
-    			nd-router-solicit,
-    			nd-neighbor-solicit,
-    			nd-neighbor-advert
-    		} 
-    		meta priority set 0:6 
-    		ip6 dscp set cs6
-    	ip6 daddr { fe80::/10, ff02::/16 } 
-    		udp sport 546 
-    		udp dport 547 
-    		meta priority set 0:6 
-    		ip6 dscp set cs6
-    }
-    
-    chain mangle_postrouting {
-    	type filter hook postrouting priority mangle
-    	policy accept
-    
-    	oifname $iface rt ipsec missing jump prio_orange
-    }
-}
-
    -
  • a simpler (better?) version :
  • -
# ipv4 (for renew)
-table ip mangle {
-	chain prio_orange {
-       	udp sport 68 udp dport 67 meta priority set 0:6 ip dscp set cs6 counter comment "mangle-prio_orange_DHCP"
-	}
-
-    chain POSTROUTING {
-    	type filter hook postrouting priority mangle; policy accept;
-        oifname $iface counter jump prio_orange comment "mangle-postrouting_orange"
-   }
-}
-
-# ipv6
-table ip6 mangle {
-	chain prio_orange {
-    	icmpv6 type { nd-router-solicit, nd-neighbor-solicit, nd-neighbor-advert } meta priority set 0:6 ip6 dscp set cs6 counter comment "mangle6-prio_orange_ICMP"
-       	udp sport 546 udp dport 547 meta priority set 0:6 ip6 dscp set cs6 counter comment "mangle6-prio_orange_DHCP"
-	}
-
-    chain POSTROUTING {
-    	type filter hook postrouting priority mangle; policy accept;
-        oifname $iface ip6 daddr { fe80::/10, ff02::/16 } counter jump prio_orange comment "mangle6-postrouting_orange"
-   }
-}
-

From systemd v253, new options exist to modify COS and DSCP to 6 on dhcpv4 (https://github.com/systemd/systemd/pull/25904).
-But, you always have to modify COS(PCP) and DSCP for dhcpv6 (and icmpv6). Todo this use the previous nftables rules.

Mikrotik (RouterOS)

DHCPv4 clients use RAW SOCKETS for DISCOVER/REQUEST (init) requests and BSD/UDP SOCKETS for RENEW requests.
-In consequence, you CANNOT use netfilter mangle rules to change PCP and DSCP. You MUST use L2 rules (switch rules or bridge filters).

Moreover, Mikrotik limit its switch rules to INGRESS, switch rules cannot be used for EGRESS. In other terms, to change COS/PCP and DSCP on DHCPv4 requests you must use a different device (switch/router) in front of your main router.

To bypass this limitation, you can use bridge filters (instead of switch rules), BUT it is not recommended in performance point view because the CPU will be in charge of these filters.

If you want to use switch rules : ISP Fiber --- Switch (switch rules) --- Router (DHCP clients)
-If you want to use bridge filters : ISP Fiber --- Router (DHCP clients + bridge filters)

note : fe007::/7 == fe80::/10 + ff02::/16

    -
  • on switch (CRS/CCR211x) with switch rules :
  • -
/interface ethernet switch rule
-add comment="orange1 dhcp4 COS6" dst-port=67 mac-protocol=ip new-vlan-priority=6 ports=sfp1.router protocol=udp switch=switch1 vlan-id=832
-add comment="orange1 dhcp6 COS6" dst-port=547 mac-protocol=ipv6 new-vlan-priority=6 ports=sfp1.router protocol=udp switch=switch1 vlan-id=832
-add comment="orange1 icmp6 COS6" dst-address6=fe00::/7 mac-protocol=ipv6 new-vlan-priority=6 ports=sfp1.router protocol=icmp switch=switch1 vlan-id=832
-add comment="orange1 arp COS6" mac-protocol=arp new-vlan-priority=6 ports=sfp1.router switch=switch1 vlan-id=832
-
    -
  • on router (CCR2004 - WITHOUT switch chipset ) with brdige filters :
  • -
/interface bridge filter
-add action=set-priority chain=output comment="orange1 dhcp4 COS6" disabled=yes dst-port=67 ip-protocol=udp log=yes log-prefix="orange1 COS6_DHCP4" mac-protocol=ip new-priority=6 out-interface=bridge-wan1 passthrough=yes
-add action=set-priority chain=output comment="orange1 dhcp6 COS6" disabled=yes dst-port=547 ip-protocol=udp log=yes log-prefix="orange1 COS6_DHCP6" mac-protocol=ipv6 new-priority=6 out-interface=bridge-wan1 passthrough=yes
-add action=set-priority chain=output comment="orange1 icmp6 COS6" disabled=yes ip-protocol=icmpv6 log-prefix="orange1 COS6_ICMP6" mac-protocol=ipv6 new-priority=6 out-interface=bridge-wan1 passthrough=yes
-add action=set-priority chain=output comment="orange1 arp COS6" disabled=yes log=yes log-prefix="orange1 COS6_ARP" mac-protocol=arp new-priority=6 out-interface=bridge-wan1 passthrough=yes
-
    -
  • firewall mangle rules are ONLY for DHCPv6 client requests (IPv6 do not use RAW SOCKETS for DHCP) :
  • -
/ipv6 firewall mangle
-add action=set-priority chain=output comment="orange1 icmp6 133RS COS6" dst-address=ff00::/8 icmp-options=133:0-255 new-priority=6 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
-add action=set-priority chain=output comment="orange1 icmp6 136NA COS6" dst-address=fe80::ba0:bab/128 icmp-options=136:0-255 new-priority=6 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
-add action=set-priority chain=output comment="orange1 icmp6 135NS COS6" dst-address=fe80::ba0:bab/128 icmp-options=135:0-255 new-priority=6 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
-add action=set-priority chain=output comment="orange1 dhcp6 COS6" dst-port=547 new-priority=6 out-interface=bridge-wan1 passthrough=yes protocol=udp src-port=546
-

DSCP (optional)

This is optional in 2023, and not really required (DSCP 48 match with 6 on layer 2)
-note : if do not work with new-dscp=48, try new-dscp=6

    -
  • original version :
  • -
/ipv6 firewall mangle
-add action=change-dscp chain=output comment="orange1 icmp6 133RS DSCP6" dst-address=ff00::/8 icmp-options=133:0-255 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
-add action=change-dscp chain=output comment="orange1 icmp6 136NA DSCP6" dst-address=fe80::ba0:bab/128 icmp-options=136:0-255 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
-add action=change-dscp chain=output comment="orange1 icmp6 135NS DSCP6" dst-address=fe80::ba0:bab/128 icmp-options=135:0-255 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
-add action=change-dscp chain=output comment="orange1 dhcp6 DSCP6" dst-port=547 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=udp src-port=546
-
    -
  • better version with postrouting (you could also use output chain) :
  • -
/ip firewall mangle
-add action=change-dscp chain=postrouting comment="dhcp4 DSCP6" dst-port=67 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=udp src-port=68
-
-/ipv6 firewall mangle
-add action=jump chain=postrouting comment="jump prio_orange_icmp6" dst-address=fe00::/7 jump-target=prio_orange_icmp6 out-interface=bridge-wan1 protocol=icmp6
-add action=jump chain=postrouting comment="jump prio_orange_dhcp6" dst-address=ff00::/8 dst-port=547 jump-target=prio_orange_dhcp6 out-interface=bridge-wan1 protocol=udp src-port=546
-
-/ipv6 firewall mangle
-add action=set-priority chain=prio_orange_icmp6 comment="icmp6 136NA COS6" dst-address=fe80::ba0:bab/128 icmp-options=136:0-255 new-priority=6 passthrough=yes protocol=icmp6
-add action=change-dscp chain=prio_orange_icmp6 comment="icmp6 136NA DSCP6" dst-address=fe80::ba0:bab/128 icmp-options=136:0-255 new-dscp=48 passthrough=yes protocol=icmp6
-add action=set-priority chain=prio_orange_icmp6 comment="icmp6 135NS COS6" dst-address=fe80::ba0:bab/128 icmp-options=135:0-255 new-priority=6 passthrough=yes protocol=icmp6
-add action=change-dscp chain=prio_orange_icmp6 comment="icmp6 135NS DSCP6" dst-address=fe80::ba0:bab/128 icmp-options=135:0-255 new-dscp=48 passthrough=yes protocol=icmp6
-add action=set-priority chain=prio_orange_icmp6 comment="icmp6 133RS COS6" dst-address=ff00::/8 icmp-options=133:0-255 new-priority=6 passthrough=yes protocol=icmp6
-add action=change-dscp chain=prio_orange_icmp6 comment="icmp6 133RS DSCP6" dst-address=ff00::/8 icmp-options=133:0-255 new-dscp=48 passthrough=yes protocol=icmp6
-add action=accept chain=prio_orange_icmp6 comment="ACCEPT"
-
-/ipv6 firewall mangle
-add action=set-priority chain=prio_orange_dhcp6 comment="dhcp6 COS6" new-priority=6 passthrough=yes
-add action=change-dscp chain=prio_orange_dhcp6 comment="dhcp6 DSCP6" new-dscp=48 passthrough=yes
-add action=accept chain=prio_orange_dhcp6 comment="ACCEPT"
-

DHCP clients

systemd-networkd

note : to check interface status, use networkctl -s status <iface>

    -
  • /etc/systemd/network/wan1.network :
  • -
[Match]
-Name=wan1
-[Network]
-ConfigureWithoutCarrier=true
-Address=192.168.2.254/24
-Description=WAN1 Orange1
-VLAN=orange1
-IPv6AcceptRA=no
-[DHCP]
-UseDNS=false
-
    -
  • /etc/systemd/network/orange1.netdev :
  • -
[NetDev]
-Name=orange1
-Kind=vlan
-MACAddress=<livebox_macaddr>
-[VLAN]
-Id=832
-EgressQOSMaps=6-6 # systemd v253 only
-
    -
  • /etc/systemd/network/orange1.network :
  • -
[Match]
-Name=orange1
-
-[Network]
-Description=Orange1
-LinkLocalAddressing=ipv6
-DHCP=yes
-IPForward=yes
-IPv6AcceptRA=yes
-DHCPPrefixDelegation=yes
-#Address=<orange1_ipext>
-Address=<orange1_ip6prefix_2>::254/64
-
-[DHCPv4]
-ClientIdentifier=mac
-VendorClassIdentifier=sagem
-UserClass=FSVDSL_livebox.Internet.softathome.Livebox6
-SendOption=90:string:<authentication_string>
-UseHostname=no
-UseDNS=no
-UseDomains=no
-UseNTP=no
-#UseAddress=no
-RouteMetric=0
-IPServiceType=CS6 # already default
-SocketPriority=6 # systemd v253 only
-
-[DHCPv6]
-# prefer DUIDType=link-layer (mac_addr of interface MUST be equal to livebox_macaddr>) ; try DUIDRawData=00:03:00:01:<livebox_macaddr> (should work) or DUIDRawData=00:03:00::<livebox_macaddr> (should not work) ; reset ONT could be required
-#DUIDRawData=00:03:00:01:<livebox_macaddr>
-DUIDType=link-layer
-# UserClass and SendOption=15:string: are equivalent
-UserClass=FSVDSL_livebox.Internet.softathome.Livebox6
-#UserClass=\x00\x2b\x46\x53\x56\x44\x53\x4c\x5f\x6c\x69\x76\x65\x62\x6f\x78\x2e\x49\x6e\x74\x65\x72\x6e\x65\x74\x2e\x73\x6f\x66\x74\x61\x74\x68\x6f\x6d\x65\x2e\x4c\x69\x76\x65\x62\x6f\x78\x36
-#SendOption=15:string:\x00\x2b\x46\x53\x56\x44\x53\x4c\x5f\x6c\x69\x76\x65\x62\x6f\x78\x2e\x49\x6e\x74\x65\x72\x6e\x65\x74\x2e\x73\x6f\x66\x74\x61\x74\x68\x6f\x6d\x65\x2e\x4c\x69\x76\x65\x62\x6f\x78\x36
-SendOption=11:string:<authentication_string>
-SendOption=16:string:\x00\x00\x04\x0e\x00\x05\x73\x61\x67\x65\x6d
-UseHostname=no
-UseDNS=no
-UseDomains=no
-UseNTP=no
-UseAddress=no
-RouteMetric=1024
-WithoutRA=solicit
-RapidCommit=no
-
-[IPv6AcceptRA]
-DHCPv6Client=always
-UseDNS=no
-UseDomains=no
-
-[DHCPPrefixDelegation]
-SubnetId=0x2
-UplinkInterface=:self
-Announce=no
-#Assign=no
-
    -
  • /etc/system/systemd-networkd.service.d/10-debug.conf :
  • -
[Service]
-Environment=SYSTEMD_LOG_LEVEL=debug
-

note : since systemd v253, new options [EgressQOSMaps, IPServiceType, SocketPriority] exists to modify COS and DSCP to 6 on DHCPv4 (https://github.com/systemd/systemd/pull/25904).

WARNING : You always have to modify COS and DSCP for DHCPv6 (and ICMPv6). Todo this use the previous nftables rules (see paragraph).

dhcpcd (NetworkConfiguration)

https://roy.marples.name/projects/dhcpcd
-https://github.com/NetworkConfiguration/dhcpcd

noipv4ll
-nohook hostname resolv.conf timesyncd.conf
-allowinterfaces orange1
-debug
-logfile /var/log/dhcpcd.log
-noauthrequired
-noarp
-noipv6rs
-
-interface orange1
-	iaid	xxxxxxxx
-	ia_pd	xxxxxxxx br0//64
-	ipv6rs
-	clientid
-	userclass FSVDSL_livebox.Internet.softathome.Livebox6
-	vendclass 1038 sagem
-	vendorclassid sagem
-	broadcast
-	option subnet_mask routers domain_name_servers domain_name broadcast_address dhcp_lease_time dhcp_renewal_time dhcp_rebinding_time domain_search sip_server 125 auth
-	option dhcp6_vivso dhcp6_name_servers dhcp6_domain_search dhcp6_auth
-	nooption 33 57
-	authprotocol token 0x123/0x456
-	authtoken 0x456 "" forever 64:68:63:70:6c:69:76:65:62:6f:78:66:72:32:35:30
-	authtoken 0x123 "" forever 1a:09:00:00:05:58:01:03:41:01:0d:66:74:69:2f:...
-

dhclient

 WARNING : ISC dhclient is deprecated since 2023, prefer systemd-networkd

Do not forget to :

    -
  • -

    define Enter and Exit hooks

    -
  • -
  • -

    use so_priority or LD_PRELOAD to force packets COS6

    -
  • -
  • -

    if necessary and to avoid /etc/resolv.conf overwrite, use chattr +i /etc/resolv.conf

    -
  • -
  • -

    launch command lines :

    -
  • -
iface="orange1"
-cfgdir=...
-leasedir=...
-piddir=...
-dhclient -4 -cf ${cfgdir}/${iface}_4.conf -pf ${piddir}/${iface}_4.pid -lf ${leasedir}/${iface}_4.leases $iface 
-dhclient -6 -cf ${cfgdir}/${iface}_6.conf -pf ${piddir}/${iface}_6.pid -lf ${leasedir}/${iface}_6.leases -P -nw $iface
-
    -
  • /etc/dhclient/orange1_4.conf :
  • -
option rfc3118-authentication code 90 = string;
-interface "orange1" {
-  timeout 60;
-  retry 1;
-  select-timeout 0;
-  #supersede dhcp-renewal-time 30;
-  #supersede dhcp-rebinding-time 60;
-  #supersede dhcp-lease-time 90;
-  send vendor-class-identifier "sagem";
-  send user-class "+FSVDSL_livebox.Internet.softathome.Livebox4";
-  send rfc3118-authentication 00:00:00:00:00:00:<authentication_string>;
-  send dhcp-client-identifier 01:<livebox_mac>;
-  request subnet-mask, routers, broadcast-address;
-  #request subnet-mask, routers, domain-name-servers, domain-name, broadcast-address, dhcp-lease-time, dhcp-renewal-time, dhcp-rebinding-time, rfc3118-authentication;
-  #request subnet-mask, broadcast-address, dhcp-lease-time, dhcp-renewal-time, dhcp-rebinding-time, rfc3118-authentication;
-}
-
    -
  • /etc/dhclient/orange1_6.conf :
  • -
option dhcp6.auth code 11 = string;
-option dhcp6.userclass code 15 = string;
-option dhcp6.vendorclass code 16 = string;
-interface "orange1" {
-  timeout 60;
-  retry 1;
-  select-timeout 0;
-  send dhcp6.vendorclass 00:00:04:0e:00:05:73:61:67:65:6d;
-  send dhcp6.userclass 00:2b:46:53:56:44:53:4c:5f:6c:69:76:65:62:6f:78:2e:49:6e:74:65:72:6e:65:74:2e:73:6f:66:74:61:74:68:6f:6d:65:2e:4c:69:76:65:62:6f:78:34;
-  send dhcp6.auth 00:00:00:00:00:00:00:00:<authentication_string>;
-  send dhcp6.client-id 00:03:00:01:<livebox_mac>;
-  also request dhcp6.auth, dhcp6.vendorclass, dhcp6.userclass, dhcp6.vendor-opts;
-}
-

so_priority (LD_PRELOAD)

This utility must be used with dhcp client utility (like dhclient or dhpcd, NOT systemd). It provide the ability to run the dhcp client with a modified Socket Priority.
-WARNING : It is NOT compatible with systemd-networkd (which have built-in params to do COS6) ! 

https://git.kindwolf.org/so_priority.so/
-https://lafibre.info/remplacer-livebox/petit-ld_preload-pour-amateurs-de-setsockopt/

compilation :

gcc -shared -ldl -fPIC so_priority.c -o so_priority.so
-

usage :

SO_PRIORITY_DEBUG=1 SO_PRIORITY_VALUE=6 LD_PRELOAD=/path/to/so_priority.so program arg1 arg2
-

source code :

/*
-        Set SO_PRIORITY right after each socket() call.
-        Compile with: gcc -shared -ldl -fPIC so_priority.c -o so_priority.so
-        Usage: SO_PRIORITY_DEBUG=1 SO_PRIORITY_VALUE=6 LD_PRELOAD=/path/to/so_priority.so program arg1 arg2
-
-        (c) 2020 - Xavier Guerrin
-        This program is free software. It comes without any warranty, to
-        the extent permitted by applicable law. You can redistribute it
-        and/or modify it under the terms of the Do What The Fuck You Want
-        To Public License, Version 2, as published by Sam Hocevar. See
-        http://www.wtfpl.net/ for more details.
-*/
-
-#define _GNU_SOURCE /* RTLD_NEXT */
-#include <dlfcn.h> /* dlsym, dlerror */
-#include <errno.h> /* errno */
-#include <stdio.h> /* dprintf */
-#include <stdlib.h> /* atoi, getenv */
-#include <string.h> /* strerror */
-#include <sys/types.h> /* setsockopt */
-#include <sys/socket.h> /* setsockopt */
-
-#ifndef SOPRIORITY_SO_NAME
-#define SOPRIORITY_SO_NAME "so_priority.so"
-#endif
-#ifndef SOPRIORITY_VALUE_EV
-#define SOPRIORITY_VALUE_EV "SO_PRIORITY_VALUE"
-#endif
-#ifndef SOPRIORITY_DEBUG_EV
-#define SOPRIORITY_DEBUG_EV "SO_PRIORITY_DEBUG"
-#endif
-
-typedef int (*socket_function_type)(int, int, int);
-
-/* Pointer to the actual socket symbol. */
-socket_function_type so_priority_socket = NULL;
-
-/* SO_PRIORITY value to set; can be configured using the SO_PRIORITY_VALUE environment variable. */
-int so_priority_value = 0;
-/* Debug level; can be configured using the SO_PRIORITY_DEBUG environment variable. */
-int so_priority_debug = 0;
-int so_priority_known = 0;
-
-/* Ask the linker to provide the actual "socket" symbol: */
-static int so_priority_get_socket() {
-        char *error_string;
-        so_priority_socket = (socket_function_type)dlsym(RTLD_NEXT, "socket");
-        if (!so_priority_socket) {
-                error_string = dlerror();
-                if (error_string) {
-                        dprintf(2, "%s: unable to find the actual socket symbol: %s\n", SOPRIORITY_SO_NAME, error_string);
-                }
-                else {
-                        dprintf(2, "%s: unable to find the actual socket symbol\n", SOPRIORITY_SO_NAME);
-                }
-                return 0;
-        }
-        return 1;
-}
-
-/* Read the priority value from the environment. */
-static void so_priority_set_options() {
-        char *str;
-        str = getenv(SOPRIORITY_VALUE_EV);
-        if (str) so_priority_value = atoi(str);
-        str = getenv(SOPRIORITY_DEBUG_EV);
-        if (str) so_priority_debug = atoi(str);
-        so_priority_known = 1;
-}
-
-/* Wrapper around the actual socket() function that sets SO_PRIORITY by calling setsockopt(). */
-int socket(int domain, int type, int protocol) {
-        int ret, setsockopt_errno, socket_errno, sockfd;
-
-        if (!so_priority_socket && !so_priority_get_socket()) {
-                errno = ENOENT;
-                return -1;
-        }
-        /* Actually call socket(): */
-        sockfd = so_priority_socket(domain, type, protocol);
-        /* Do not call setsockopt() if socket() failed: */
-        if (sockfd < 0) return sockfd;
-    
-        /* Time for the actual work: */
-        socket_errno = errno;
-    
-        if (!so_priority_known) so_priority_set_options();
-        ret = setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &so_priority_value, sizeof(so_priority_value));
-        /* Ignore setsockopt() errors, except for debugging purposes. */
-        if (so_priority_debug) {
-                setsockopt_errno = errno;
-                dprintf(2, "%s: setsockopt(%d, SOL_SOCKET, SO_PRIORITY, %d, %zu) returned %d",
-                        SOPRIORITY_SO_NAME, sockfd, so_priority_value, sizeof(so_priority_value), ret);
-                if (ret < 0) dprintf(2, "; errno is %d: %s", setsockopt_errno, strerror(setsockopt_errno));
-                dprintf(2, "\n");
-        }
-    
-        errno = socket_errno;
-        return sockfd;
-}
-

Archlinux PKGBUILD :

# https://git.kindwolf.org/so_priority.so/
-# https://lafibre.info/remplacer-livebox/petit-ld_preload-pour-amateurs-de-setsockopt/
-# USAGE : SO_PRIORITY_DEBUG=1 SO_PRIORITY_VALUE=6 LD_PRELOAD=/path/to/so_priority.so program arg1 arg2
-
-pkgname=so_priority
-pkgver=1.0
-pkgrel=0
-
-pkgdesc='Set SO_PRIORITY (aka skb->priority) right after each socket() call.'
-arch=('i686' 'x86_64')
-url="https://git.kindwolf.org/so_priority.so"
-license=('GPL3')
-
-source=(https://git.kindwolf.org/so_priority.so/raw/master/so_priority.c)
-
-validpgpkeys=(
-        'SKIP'
-)
-sha256sums=(
-        'SKIP')
-
-build() {
-        cd "$srcdir"/
-        gcc -shared -ldl -fPIC so_priority.c -o so_priority.so
-}
-
-package() {
-        cd "$srcdir"/
-        for s in *.so; do
-                install -Dm755 $s "$pkgdir/usr/lib/so_priority/$s"
-        done
-}
-

debug and troubleshoot

    -
  • -

    If you get no answer from Orange DHCP server and everything seems to be ok, try to force release multiple times and disconnect a few minutes the ONT (fiber link) to force DHCP lease expiration

    -
  • -
  • -

    Sometimes, when switching hardware or interface on the same fiber link, you will encounter IAID issue. In this case the DHCPv6 server (ISP) will give NO PREFIX answer. You have to disconnect fiber link for at least 10-20min. Then reconnect and retry DHCP requests. You should have no issue with DHCPv4. Check also option 17 (vendor_opt) answer, if everything is correct, try again to disconnect fiber link for a few minutes.

    -
  • -
  • -

    Finally try to regenerate authentication options (90 for DHCPv4 and 11 for DHCPv6). Sometimes, it could be necessary to regenerate authentication options, after a few months for example...

    -
  • -
  • -

    For COS 6 verification check the first line tcpdump trace, check :

    -
  • -
'[vlan ${vlan}, p X]' : ..., ethertype 802.1Q (0x8100), length XXX: vlan ${vlan}, p X, ethertype IPv4 (0x0800), ...
-

tcpdump command lines :

# prefer :
-tcpdump -vnei wan1 '(udp port 546 or port 547) or icmp6'
-# alternatives :
-tcpdump -i wan1 -ne -vv "(udp port 546 and port 547)"
-tcpdump -i wan1 -vvv -n ip6  “(udp port 546 and port 547)”
-tcpdump -vnes0 -i wan1 udp port 67 or port 68 or port 546 or port 547
-

systemd-networkd

    -
  • use DUIDType=link-layer
  • -
  • from tcpdump : client-ID hwaddr 44d4540axxxx ; IA_PD-prefix 2a01:cb15:3e4:xxxx::/56 ; IA_PD IAID:22882960xx
  • -
  • check interface status : networkctl status <iface>
  • -

DHCP6 Client IAID: 0x8864a065
-DHCP6 Client DUID: DUID-LL:000144d4540axxxx0000

tcpdump sample trace :

dhcp6 solicit   (xid=6461b1 (rapid-commit) (IA_PD IAID:22882960xx T1:0 T2:0) (Client-FQDN) (user-class) (option-request opt_82) (client-ID hwaddr type 1 44d4540axxxx)
-dhcp6 advertise (xid=6461b1 (IA_PD IAID:22882960xx T1:83812 T2:207360 (IA_PD-prefix 2a01:cb15:3e4:xxxx::/56 pltime:259200 vltime:259200)) (server-ID vid 0000055844455348) (client-ID hwaddr type 1 44d4540axxxx)
-dhcp6 request   (xid=76595c (server-ID vid 0000055844455348) (IA_PD IAID:22882960xx T1:0 T2:0 (IA_PD-prefix 2a01:cb15:3e4:xxxx::/56 pltime:0 vltime:0)) (Client-FQDN) (user-class) (client-ID hwaddr type 1 44d4540axxxx)
-dhcp6 reply     (xid=76595c (IA_PD IAID:22882960xx T1:86413 T2:207360 (IA_PD-prefix 2a01:cb15:3e4:xxxx::/56 pltime:259200 vltime:259200)) (server-ID vid 0000055844455348) (client-ID hwaddr type 1 44d4540axxxx)
-

Mikrotik (RouterOS)

Sometimes, when switching hardware or interface on the same fiber link, you will encounter IAID issue. In this case ipv6 DHCP client will give you NO PREFIX answer from DHCP server.
-https://wiki.mikrotik.com/wiki/Manual:IPv6/DHCP_Client
-To determine what IAID will be used, convert internal ID of an interface on which DHCP client is running from hex to decimal. For example, DHCP client is running on interface pppoe-out1. To get internal ID use following command :
-/interface> :put \[find name="vlan832-orange1"]
-For example, you will get : *15
-Now convert hex value 15 to decimal and you get IAID=21

routerOS command line to snif interface and send to a remote host :

xxxxxx] > /tool/sniffer/export 
-# apr/20/2023 19:01:18 by RouterOS 7.6
-# software id = xxxxxx
-#
-# model = CCR2004-1G-12S+2XS
-# serial number = xxxxxxx
-/tool sniffer
-set file-limit=100000KiB filter-interface=br-wan filter-ip-protocol=udp filter-port=bootps,bootpc,546,547 filter-stream=yes memory-limit=5000KiB memory-scroll=no streaming-enabled=yes streaming-server=192.168.xxx.xxx
-

Sources

There are lot of sources which helped me to write this article. Here are the most importants.

https://lafibre.info/remplacer-livebox/durcissement-du-controle-de-loption-9011-et-de-la-conformite-protocolaire/
-https://lafibre.info/remplacer-livebox/guide-de-connexion-fibre-directement-sur-un-routeur-voire-meme-en-2gbps/
-https://lafibre.info/remplacer-livebox/index-des-solutions-de-remplacement-de-la-livebox/

Special thanks to lafibre.info forum and its members !

\ No newline at end of file diff --git a/orange/own_router.html b/orange/own_router.html new file mode 100644 index 0000000..33869b9 --- /dev/null +++ b/orange/own_router.html @@ -0,0 +1,692 @@ + + Bring Your Own Router Orange ISP + + + + + + + + + + + +

Bring Your Own Router Orange ISP

Version 20240713

This document describe how-to configure DHCP clients for ISP Orange in France. This could be used to remove the Livebox and prefer your own router…

Requirements

You must already have a working ONT/ONU registered on Orange fiber infrastructure. ONT/ONU are registering on Orange infrastructure with serial number.
+For informations, Orange use serial_number and vendor_id to allow a ONT/ONU to register.
+You could see this other article https://medium.com/@cyayon/configure-ont-leox-lxt-010h-d-for-orange-isp-4ef4b793ca7b.
+To configure properly your ONU/ONT, check dedicated topics and forums...

2023 evolutions

ipv4

    +
  • user-class [77] : "FSVDSL_livebox.Internet.softathome.Livebox6" or "2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
  • +
  • vendor-class-identifier [60] : "sagem" or "0x736167656d"
  • +
  • rfc3118-authentication [90] : "authentication string (00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0Dxxx)"
  • +
  • dhcp-client-identifier [61] : "01:<mac_addr>" or "01<mac_addr>" or "0x01<mac_addr>"
  • +

ipv6

    +
  • user-class [15] : "002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
  • +
  • class-identifier [16] : "00:00:04:0e:00:05:73:61:67:65:6d" or "0x0000040e0005736167656d"
  • +
  • authentication [11] : "authentication string (00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0Dxxx)"
  • +
  • client DUID [1] : "00:03:00:01:<mac_addr>" or "00030001<mac_addr>" or "0x00030001<mac_addr>"
  • +

notes

    +
  • All DHCP requests must be done with COS6 (DSCP6 recommended too).
  • +
  • When you switch hardware (new router / ONU / ONT) you have to wait a few minutes with DISCONNECTED fiber link. DHCP IAID are dynamically generated by hardware equipments and Orange is waiting for a single IAID per client. To force expiration, the only way is to disconnect fiber 15-30 minutes and wait… The issue is that you will NOT get DHCPv6 prefix (NoPrefixAvail) from Orange.
  • +
  • note authentication : ipv4 and ipv6 strings MUST be equals
  • +
  • note user-class : user-class (ipv4:77 / ipv6:15) must match ipv4 and ipv6 (with different formats)
  • +

string2hex(FSVDSL_livebox.Internet.softathome.Livebox4) -> "46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7834"
+user-class string = "2b" + string2hex() ; ipv6 string = "00" + "ipv4 string"

WARNING : take care of case (livebox vs Livebox)

[ipv4:77] : "FSVDSL_livebox.Internet.softathome.Livebox4" or "0x2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7834"
+[ipv6:15] : "002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7834"
+
+[ipv4:77] : "FSVDSL_livebox.Internet.softathome.Livebox5" or "0x2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7835"
+[ipv6:15] : "002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7835"
+
+[ipv4:77] : "FSVDSL_livebox.Internet.softathome.Livebox6" or "0x2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
+[ipv6:15] : "002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
+

WARNING : if dhcp client use raw or not, final (and true) string to have in tcpdump sniff should be (for LB6) :

[ipv4:77] : "4d2c2b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
+[ipv6:15] : "000f002d002b46535644534c5f6c697665626f782e496e7465726e65742e736f66746174686f6d652e4c697665626f7836"
+
    +
  • note vendor-opts : vendor-opts (or vendor_opts for vendor specific informations, IS NOT REQUIRED) [17] : "00:00:05:58:00:06:00:0e:49:50:56:36:5f:52:45:51:55:45:53:54:45:44" or "0x000005580006000e495056365f524551554553544544”, entreprise id "Orange" 4 octets 00000558 + 2 octets code 0006 + 14 octets data: 495056365f524551554553544544 ("IPV6_REQUESTED")
  • +
  • note systemd-networkd : each string must converted from "aa:bb:cc:dd:ee:....." to xaaxbbxbbxccxddxeex...." (replace ":" with "x") echo "aa:bb:cc:dd:ee" | sed 's/^/\\\x/ ; s/:/\\\x/g'
  • +

systemd-network sample config :

[DHCPv4]
+ClientIdentifier=mac
+VendorClassIdentifier=sagem
+UserClass=FSVDSL_livebox.Internet.softathome.Livebox6
+SendOption=90:string:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1A\x09\x00\x00\x05\x58\x01\x03\x41\x01\x0D\x66\x74\x69...
+[DHCPv6]
+DUIDType=link-layer
+# Bring Your Own Router Orange ISP
+UserClass=FSVDSL_livebox.Internet.softathome.Livebox6
+#UserClass=\x00\x2b\x46\x53\x56\x44\x53\x4c\x5f\x6c\x69\x76\x65\x62\x6f\x78\x2e\x49\x6e\x74\x65\x72\x6e\x65\x74\x2e\x73\x6f\x66\x74\x61\x74\x68\x6f\x6d\x65\x2e\x4c\x69\x76\x65\x62\x6f\x78\x36
+#SendOption=15:string:\x00\x2b\x46\x53\x56\x44\x53\x4c\x5f\x6c\x69\x76\x65\x62\x6f\x78\x2e\x49\x6e\x74\x65\x72\x6e\x65\x74\x2e\x73\x6f\x66\x74\x61\x74\x68\x6f\x6d\x65\x2e\x4c\x69\x76\x65\x62\x6f\x78\x36
+SendOption=11:string:\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1A\x09\x00\x00\x05\x58\x01\x03\x41\x01\x0D\x66\x74\x69...
+SendOption=16:string:\x00\x00\x04\x0e\x00\x05\x73\x61\x67\x65\x6d
+

Option Request Option

The DHCPv6 ORO (Option Request Option, code 6), the following options are required :
+Option: Option Request (6) - Length: 8 - Value: 000b001100170018
+Requested Option code: Authentication (11)
+Requested Option code: Vendor-specific Information (17)
+Requested Option code: DNS recursive name server (23)
+Requested Option code: Domain Search List (24)

But, for the RFC8415 (https://datatracker.ietf.org/doc/html/rfc8415#section-21.7), option 11 (Authentication) is forbidden.
+For Orange, it is NOT mandatory to include option 11 in SOLLICIT/REQUEST requests. You can only keep options 17,23,24.

Authentication

note : You could also use https://jsfiddle.net/kgersen/3mnsc6wy/

shell script to generate authentication string :

#!/bin/bash
+# You could also use https://jsfiddle.net/kgersen/3mnsc6wy/
+# Version 20221214
+
+[ -z "$2" ] && echo "usage : $0 '<fti/login>' '<passwd>'" && exit 1
+
+login="$1" ; pass="$2"
+
+tohex() {
+      for h in $(echo $1 | sed "s/\(.\)/\1 /g"); do printf %02x \'$h; done
+}
+
+addsep() {
+      echo $(echo $1 | sed "s/\(.\)\(.\)/:\1\2/g")
+}
+
+r=$(dd if=/dev/urandom bs=1k count=1 2>&1 | md5sum | cut -c1-16)
+id=${r:0:1}
+h=3C12$(tohex ${r})0313$(tohex ${id})$(echo -n ${id}${pass}${r} | md5sum | cut -c1-32)
+str=$(addsep $(tohex ${login})${h})
+
+echo "# dhclient"
+echo "## ipv4"
+echo "send rfc3118-authentication 00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0D${str};"
+echo "## ipv6"
+echo "send dhcp6.auth 00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0D${str};"
+
+echo
+echo "# systemd-networkd"
+echo "## [DHCPv4]"
+str2=`echo "00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0D${str}" | sed 's/^/\\\x/ ; s/:/\\\x/g'`
+echo "SendOption=90:string:${str2}"
+echo "## [DHCPv6]"
+echo "SendOption=11:string:${str2}"
+
+echo
+echo "# mikrotik routeros"
+echo "## DHCPv4"
+echo "/ip dhcp-client option"
+str2=`echo "00:00:00:00:00:00:00:00:00:00:00:1A:09:00:00:05:58:01:03:41:01:0D${str}" | sed 's/://g'`
+echo "add code=90 name=authsend value=0x${str2}"
+echo "## DHCPv6"
+echo "/ipv6 dhcp-client option"
+echo "add code=11 name=authsend value=0x${str2}"
+

COS 6

DHCP packets MUST be flagged COS/PCP and DSCP class-of-service
+However, DSCP is not mandatory but recommended.

DHCPv4 clients use RAW SOCKETS for DISCOVER/REQUEST (init) requests and BSD/UDP SOCKETS for RENEW requests.
+In consequence, you CANNOT use netfilter mangle rules to change COS/PCP and DSCP. You MUST use L2 filtering.

+IMPORTANT NOTICE : Since kernel 5.7, the netfilter netdev egress filter could match DHCP packets. See below netfilter nftables egress filter, it could be fun to try without tc script…

On Linux L2 filtering can be done with tc (traffic-control) tool. On Mikrotik router there switch rules or bridge filters.

linux tc

#!/bin/sh
+iface="orange1"
+tc_qos="0:6"
+vlan="832"
+physiface="wan1"
+mac_addr="<livebox_mac>"
+ip link add link $physiface name $iface type vlan id $vlan
+ip link set dev $iface address $mac_addr
+ip link set $iface up
+tc qdisc del dev $iface root ; tc filter del dev $iface
+tc qdisc replace dev $iface root handle 1: prio
+tc filter add dev $iface parent 1: prio 1 u32 match ip protocol 17 ff match ip dport 67 ffff action skbedit priority $tc_qos # dhcpv4
+tc filter add dev $iface parent 1: prio 2 protocol ipv6 u32 match ip6 protocol 17 ff match ip6 dport 547 ffff action skbedit priority $tc_qos # dhcpv6
+# the following is not mandatory, but recommended
+tc filter add dev $iface parent 1: prio 3 protocol 0x806 u32 match u32 0 0 action skbedit priority $tc_cos # arp
+tc filter add dev $iface parent 1: prio 4 protocol ipv6 u32 match ip6 dst fe00::/7 match ip6 protocol 58 ff action skbedit priority $tc_cos # icmpv6_dst (fe00::/7 = fe80::/10 + ff02::/16)
+# for information
+#tc filter add dev $iface parent 1: prio 4 protocol ipv6 u32 match ip6 protocol 58 ff action skbedit priority $tc_cos # icmpv6
+#tc filter add dev $iface parent 1: prio 5 protocol ip u32 match ip protocol 1 ff action skbedit priority $tc_cos # icmpv4 - SHOULD NOT BE USED !
+

DSCP (optional)

https://lafibre.info/remplacer-livebox/durcissement-du-controle-de-loption-9011-et-de-la-conformite-protocolaire/324/
+https://linuxreviews.org/Type_of_Service_(ToS)_and_DSCP_Values
+This version of tc script change COS and DSCP to 6, it should work but it has NOT been tested and work in progress.
+note DSCP : CS6 = 48 (dec) = 0xc0 (TOS-hex)

script based on tc :

#!/bin/sh
+iface="orange1"
+tc_cos="0:6"
+tc_tos="0xc0"
+tc_retain="0xfc"
+vlan="832"
+physiface="wan1"
+mac_addr="<livebox_mac>"
+ip link add link $physiface name $iface type vlan id $vlan
+ip link set dev $iface address $mac_addr
+ip link set $iface up
+tc qdisc del dev $iface root ; tc filter del dev $iface
+tc qdisc replace dev $iface root handle 1: prio
+tc filter add dev $iface parent 1: prio 1 protocol ip u32 match ip ihl 5 0xf match u16 0x0000 0x1fff at 6 match ip protocol 17 0xff match ip sport 68 0xffff match ip dport 67 0xffff action skbedit priority $tc_cos pipe action pedit pedit munge ip tos set $tc_tos retain $tc_retain pipe action csum ip4h # dhcpv4_DSCP
+tc filter add dev $iface parent 1: prio 2 protocol ipv6 u32 match ip6 protocol 17 0xff match ip6 sport 546 0xffff match ip6 dport 547 0xffff action skbedit priority $tc_cos pipe action pedit pedit munge ip6 tos set $tc_tos retain $tc_retain # dhcpv6_DSCP
+# the following is not mandatory, but recommended
+tc filter add dev $iface parent 1: prio 3 protocol arp u32 match u8 0 0 action skbedit priority $tc_cos # arp
+tc filter add dev $iface parent 1: prio 4 protocol ipv6 u32 match ip6 dst fe00::/7 match ip6 protocol 58 0xff action skbedit priority 0:6 pipe action pedit ex munge ip6 traffic_class set $tc_tos retain $tc_retain # icmpv6_dst_DSCP (fe00::/7 = fe80::/10 + ff02::/16)
+# for information - no dscp
+#tc filter add dev $iface parent 1: prio 3 protocol ipv6 u32 match ip6 protocol 17 0xff match ip6 sport 546 0xffff match ip6 dport 547 0xffff action skbedit priority $tc_cos # dhcpv6 
+#tc filter add dev $iface parent 1: prio 4 protocol ipv6 u32 match ip6 dst fe00::/7 match ip6 protocol 58 0xff action skbedit priority $tc_cos # icmpv6 dst (fe00::/7 = fe80::/10 + ff02::/16)
+

nftables

https://lafibre.info/remplacer-livebox/durcissement-du-controle-de-loption-9011-et-de-la-conformite-protocolaire/324/
+The following change DSCP and COS for ipv6 NS/NA/RS packets.
+note : nftables is NOT able to modify ipv4 DHCP packets, because they are using RAW sockets.

    +
  • original version (prefer next/simpler/better version) :
  • +
iface = orange1.832
+table inet firewall {
+	chain prio_orange {
+		meta nfproto ipv4 
+			meta priority set 0:0 
+			ip dscp set cs0
+
+    	meta nfproto ipv6 
+    		meta priority set 0:0 
+    		ip6 dscp set cs0
+    	ip6 daddr { fe80::/10, ff02::/16 } 
+    		icmpv6 type {
+    			nd-router-solicit,
+    			nd-neighbor-solicit,
+    			nd-neighbor-advert
+    		} 
+    		meta priority set 0:6 
+    		ip6 dscp set cs6
+    	ip6 daddr { fe80::/10, ff02::/16 } 
+    		udp sport 546 
+    		udp dport 547 
+    		meta priority set 0:6 
+    		ip6 dscp set cs6
+    }
+    
+    chain mangle_postrouting {
+    	type filter hook postrouting priority mangle
+    	policy accept
+    
+    	oifname $iface rt ipsec missing jump prio_orange
+    }
+}
+
    +
  • a simpler (better?) version (note the new netdev/egress filter at the end) :
  • +
# ipv4 (for renew)
+table ip mangle {
+	chain prio_orange {
+       	udp sport 68 udp dport 67 meta priority set 0:6 ip dscp set cs6 counter comment "mangle-prio_orange_DHCP"
+	}
+
+    chain POSTROUTING {
+    	type filter hook postrouting priority mangle; policy accept;
+        oifname $iface counter jump prio_orange comment "mangle-postrouting_orange"
+   }
+}
+
+# ipv6
+table ip6 mangle {
+	chain prio_orange {
+    	icmpv6 type { nd-router-solicit, nd-neighbor-solicit, nd-neighbor-advert } meta priority set 0:6 ip6 dscp set cs6 counter comment "mangle6-prio_orange_ICMP"
+       	udp sport 546 udp dport 547 meta priority set 0:6 ip6 dscp set cs6 counter comment "mangle6-prio_orange_DHCP"
+	}
+
+    chain POSTROUTING {
+    	type filter hook postrouting priority mangle; policy accept;
+        oifname $iface ip6 daddr { fe80::/10, ff02::/16 } counter jump prio_orange comment "mangle6-postrouting_orange"
+   }
+}
+
    +
  • a new method since recent kernel (> 6.xx) with netdev egress filter :
    +Filtrer les raw socket avec nftables ?
    +note : with netdev egress rules, netfilter mangle rules or traffic-control (tc script) are NO MORE NECESSARY
  • +
# netdev (for requests ipv4/ipv6)
+# note : not tested, need to tryout (tc script could NOT be required anymore)...
+table netdev filter {
+        chain egress {
+                type filter hook egress devices = $iface_wan priority filter; policy accept;
+                icmpv6 type { nd-router-solicit, nd-neighbor-solicit, nd-neighbor-advert } meta priority set 0:6 ip6 dscp set cs6 counter comment "egress_prio_orange_ICMP6"
+                udp dport 547 meta priority set 0:6 ip6 dscp set cs6 counter comment "egress_prio_orange_DHCP6"
+                udp dport 67 meta priority set 0:6 ip dscp set cs6 counter comment "egress_prio_orange_DHCP4"
+                ether type arp meta priority set 0:6 counter comment "egress_prio_orange_ARP"
+        }
+}
+

From systemd v253, new options exist to modify COS and DSCP to 6 on dhcpv4 (https://github.com/systemd/systemd/pull/25904).
+But, you always have to modify COS(PCP) and DSCP for dhcpv6 (and icmpv6). Todo this use the previous nftables rules.

Mikrotik (RouterOS)

DHCPv4 clients use RAW SOCKETS for DISCOVER/REQUEST (init) requests and BSD/UDP SOCKETS for RENEW requests.
+In consequence, you CANNOT use netfilter mangle rules to change PCP and DSCP. You MUST use L2 rules (switch rules or bridge filters).

Moreover, Mikrotik limit its switch rules to INGRESS, switch rules cannot be used for EGRESS. In other terms, to change COS/PCP and DSCP on DHCPv4 requests you must use a different device (switch/router) in front of your main router.

To bypass this limitation, you can use bridge filters (instead of switch rules), BUT it is not recommended in performance point view because the CPU will be in charge of these filters.

If you want to use switch rules : ISP Fiber --- Switch (switch rules) --- Router (DHCP clients)
+If you want to use bridge filters : ISP Fiber --- Router (DHCP clients + bridge filters)

note : fe007::/7 == fe80::/10 + ff02::/16

    +
  • on switch (CRS/CCR211x) with switch rules (before ROS 7.15) :
  • +
/interface ethernet switch rule
+add comment="orange1 dhcp4 COS6" dst-port=67 mac-protocol=ip new-vlan-priority=6 ports=sfp1.router protocol=udp switch=switch1 vlan-id=832
+add comment="orange1 dhcp6 COS6" dst-port=547 mac-protocol=ipv6 new-vlan-priority=6 ports=sfp1.router protocol=udp switch=switch1 vlan-id=832
+add comment="orange1 icmp6 COS6" dst-address6=fe00::/7 mac-protocol=ipv6 new-vlan-priority=6 ports=sfp1.router protocol=icmp switch=switch1 vlan-id=832
+add comment="orange1 arp COS6" mac-protocol=arp new-vlan-priority=6 ports=sfp1.router switch=switch1 vlan-id=832
+
    +
  • on switch (CRS/CCR211x) with switch rules (after ROS 7.15 - modify PCP and DSCP) :
  • +
/interface ethernet switch set 0 qos-hw-offloading=yes  
+/interface ethernet switch qos profile add comment="orange PCP6 DSCP48_CS6" dscp=48 name=orange-prio-bng pcp=6 traffic-class=6  
+  
+/interface ethernet switch qos port  
+	set sfp-sfpplus4 tx-manager=offline  
+	set sfp1 tx-manager=offline
+	set sfp2 tx-manager=offline 
+	set sfp3 tx-manager=offline 
+	set sfp4 tx-manager=offline 
+	set sfp5 tx-manager=offline   
+  
+/interface ethernet switch l3hw-settings  set icmp-reply-on-error=no  
+  
+/interface ethernet switch rule  
+	add comment="orange1 arp" mac-protocol=arp new-qos-profile=orange-prio-bng ports=sfp1.router switch=switch1 vlan-id=832  
+	add comment="orange1 dhcp4" dst-port=67 src-port=68 mac-protocol=ip new-qos-profile=orange-prio-bng ports=sfp1.router protocol=udp switch=switch1 vlan-id=832  
+	add comment="orange1 dhcp6" dst-port=547 src-port=546 mac-protocol=ipv6 new-qos-profile=orange-prio-bng ports=sfp1.router protocol=udp switch=switch1 vlan-id=832
+	add comment="orange1 icmp6" dst-address6=fe00::/7 mac-protocol=ipv6 new-qos-profile=orange-prio-bng ports=sfp1.router protocol=icmpv6 switch=switch1 vlan-id=832
+

note : If you prefer to modify only ICMPv6 type 133, 135, 136, then use firewall mangles rules. In this case, the following should be required to keep these modifications

/interface ethernet switch qos port  
+	set sfp1.router trust-l2=keep trust-l3=keep  
+	set sfp2.orange1-ont trust-l2=keep trust-l3=keep
+	set sfp3.orange1-onu trust-l2=keep trust-l3=keep  
+

If you have TV, add also these rules :

/interface ethernet switch qos profile add name=orange-prio-tv pcp=5 traffic-class=5
+/interface ethernet switch rule add comment="orange TV PCP5" mac-protocol=ip new-qos-profile=orange-prio-tv ports=sfp1.router switch=switch1 vlan-id=840
+
    +
  • on router (CCR2004 - WITHOUT switch chipset ) with bridge filters :
  • +
/interface bridge filter
+add action=set-priority chain=output comment="orange1 dhcp4 COS6" disabled=yes dst-port=67 ip-protocol=udp log=yes log-prefix="orange1 COS6_DHCP4" mac-protocol=ip new-priority=6 out-interface=bridge-wan1 passthrough=yes
+add action=set-priority chain=output comment="orange1 dhcp6 COS6" disabled=yes dst-port=547 ip-protocol=udp log=yes log-prefix="orange1 COS6_DHCP6" mac-protocol=ipv6 new-priority=6 out-interface=bridge-wan1 passthrough=yes
+add action=set-priority chain=output comment="orange1 icmp6 COS6" disabled=yes ip-protocol=icmpv6 log-prefix="orange1 COS6_ICMP6" mac-protocol=ipv6 new-priority=6 out-interface=bridge-wan1 passthrough=yes
+add action=set-priority chain=output comment="orange1 arp COS6" disabled=yes log=yes log-prefix="orange1 COS6_ARP" mac-protocol=arp new-priority=6 out-interface=bridge-wan1 passthrough=yes
+
    +
  • firewall mangle rules are ONLY for DHCPv6 client requests (IPv6 do not use RAW SOCKETS for DHCP) :
  • +
/ipv6 firewall mangle
+add action=set-priority chain=output comment="orange1 icmp6 133RS COS6" dst-address=ff00::/8 icmp-options=133:0-255 new-priority=6 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
+add action=set-priority chain=output comment="orange1 icmp6 136NA COS6" dst-address=fe80::ba0:bab/128 icmp-options=136:0-255 new-priority=6 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
+add action=set-priority chain=output comment="orange1 icmp6 135NS COS6" dst-address=fe80::ba0:bab/128 icmp-options=135:0-255 new-priority=6 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
+add action=set-priority chain=output comment="orange1 dhcp6 COS6" dst-port=547 new-priority=6 out-interface=bridge-wan1 passthrough=yes protocol=udp src-port=546
+

DSCP (optional)

This is optional in 2023, and not really required (DSCP 48 match with 6 on layer 2). Since ROS 7.15, it is possible to modify DSCP directly with Switch rules (see above).
+note : if it do not work with new-dscp=48, try new-dscp=6

    +
  • original version :
  • +
/ipv6 firewall mangle
+add action=change-dscp chain=output comment="orange1 icmp6 133RS DSCP6" dst-address=ff00::/8 icmp-options=133:0-255 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
+add action=change-dscp chain=output comment="orange1 icmp6 136NA DSCP6" dst-address=fe80::ba0:bab/128 icmp-options=136:0-255 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
+add action=change-dscp chain=output comment="orange1 icmp6 135NS DSCP6" dst-address=fe80::ba0:bab/128 icmp-options=135:0-255 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=icmpv6
+add action=change-dscp chain=output comment="orange1 dhcp6 DSCP6" dst-port=547 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=udp src-port=546
+
    +
  • better version with POSTROUTING (you could also use OUTPUT chain) :
  • +
/ip firewall mangle
+add action=change-dscp chain=postrouting comment="dhcp4 DSCP6" dst-port=67 new-dscp=48 out-interface=bridge-wan1 passthrough=yes protocol=udp src-port=68
+
+/ipv6 firewall mangle
+add action=jump chain=postrouting comment="jump prio_orange_icmp6" dst-address=fe00::/7 jump-target=prio_orange_icmp6 out-interface=bridge-wan1 protocol=icmp6
+add action=jump chain=postrouting comment="jump prio_orange_dhcp6" dst-address=ff00::/8 dst-port=547 jump-target=prio_orange_dhcp6 out-interface=bridge-wan1 protocol=udp src-port=546
+# you could also change DSCP6(48) for all COS6 packets (and remove all change-dscp rules in prio_orange_* chains)
+#add action=change-dscp chain=postrouting comment="DSCP6 for all COS6" new-dscp=48 out-interface=bridge-wan1 passthrough=no priority=6
+
+/ipv6 firewall mangle
+add action=set-priority chain=prio_orange_icmp6 comment="icmp6 136NA COS6" dst-address=fe80::ba0:bab/128 icmp-options=136:0-255 new-priority=6 passthrough=yes protocol=icmp6
+add action=change-dscp chain=prio_orange_icmp6 comment="icmp6 136NA DSCP6" dst-address=fe80::ba0:bab/128 icmp-options=136:0-255 new-dscp=48 passthrough=yes protocol=icmp6
+add action=set-priority chain=prio_orange_icmp6 comment="icmp6 135NS COS6" dst-address=fe80::ba0:bab/128 icmp-options=135:0-255 new-priority=6 passthrough=yes protocol=icmp6
+add action=change-dscp chain=prio_orange_icmp6 comment="icmp6 135NS DSCP6" dst-address=fe80::ba0:bab/128 icmp-options=135:0-255 new-dscp=48 passthrough=yes protocol=icmp6
+add action=set-priority chain=prio_orange_icmp6 comment="icmp6 133RS COS6" dst-address=ff00::/8 icmp-options=133:0-255 new-priority=6 passthrough=yes protocol=icmp6
+add action=change-dscp chain=prio_orange_icmp6 comment="icmp6 133RS DSCP6" dst-address=ff00::/8 icmp-options=133:0-255 new-dscp=48 passthrough=yes protocol=icmp6
+add action=accept chain=prio_orange_icmp6 comment="ACCEPT"
+
+/ipv6 firewall mangle
+add action=set-priority chain=prio_orange_dhcp6 comment="dhcp6 COS6" new-priority=6 passthrough=yes
+add action=change-dscp chain=prio_orange_dhcp6 comment="dhcp6 DSCP6" new-dscp=48 passthrough=yes
+add action=accept chain=prio_orange_dhcp6 comment="ACCEPT"
+

DHCP clients

systemd-networkd

note : to check interface status, use networkctl -s status <iface>

    +
  • /etc/systemd/network/wan1.network :
  • +
[Match]
+Name=wan1
+[Network]
+ConfigureWithoutCarrier=true
+Address=192.168.2.254/24
+Description=WAN1 Orange1
+VLAN=orange1
+IPv6AcceptRA=no
+[DHCP]
+UseDNS=false
+
    +
  • /etc/systemd/network/orange1.netdev :
  • +
[NetDev]
+Name=orange1
+Kind=vlan
+MACAddress=<livebox_macaddr>
+[VLAN]
+Id=832
+EgressQOSMaps=6-6 # systemd v253 only
+
    +
  • /etc/systemd/network/orange1.network :
  • +
[Match]
+Name=orange1
+
+[Network]
+Description=Orange1
+LinkLocalAddressing=ipv6
+DHCP=yes
+IPForward=yes
+IPv6AcceptRA=yes
+DHCPPrefixDelegation=yes
+#Address=<orange1_ipext>
+Address=<orange1_ip6prefix_2>::254/64
+
+[DHCPv4]
+ClientIdentifier=mac
+VendorClassIdentifier=sagem
+UserClass=FSVDSL_livebox.Internet.softathome.Livebox6
+SendOption=90:string:<authentication_string>
+UseHostname=no
+UseDNS=no
+UseDomains=no
+UseNTP=no
+#UseAddress=no
+RouteMetric=0
+IPServiceType=CS6 # already default
+SocketPriority=6 # systemd v253 only
+
+[DHCPv6]
+# prefer DUIDType=link-layer (mac_addr of interface MUST be equal to livebox_macaddr>) ; try DUIDRawData=00:03:00:01:<livebox_macaddr> (should work) or DUIDRawData=00:03:00::<livebox_macaddr> (should not work) ; reset ONT could be required
+#DUIDRawData=00:03:00:01:<livebox_macaddr>
+DUIDType=link-layer
+# UserClass and SendOption=15:string: are equivalent
+UserClass=FSVDSL_livebox.Internet.softathome.Livebox6
+#UserClass=\x00\x2b\x46\x53\x56\x44\x53\x4c\x5f\x6c\x69\x76\x65\x62\x6f\x78\x2e\x49\x6e\x74\x65\x72\x6e\x65\x74\x2e\x73\x6f\x66\x74\x61\x74\x68\x6f\x6d\x65\x2e\x4c\x69\x76\x65\x62\x6f\x78\x36
+#SendOption=15:string:\x00\x2b\x46\x53\x56\x44\x53\x4c\x5f\x6c\x69\x76\x65\x62\x6f\x78\x2e\x49\x6e\x74\x65\x72\x6e\x65\x74\x2e\x73\x6f\x66\x74\x61\x74\x68\x6f\x6d\x65\x2e\x4c\x69\x76\x65\x62\x6f\x78\x36
+SendOption=11:string:<authentication_string>
+SendOption=16:string:\x00\x00\x04\x0e\x00\x05\x73\x61\x67\x65\x6d
+UseHostname=no
+UseDNS=no
+UseDomains=no
+UseNTP=no
+UseAddress=no
+RouteMetric=1024
+WithoutRA=solicit
+RapidCommit=no
+
+[IPv6AcceptRA]
+DHCPv6Client=always
+UseDNS=no
+UseDomains=no
+
+[DHCPPrefixDelegation]
+SubnetId=0x2
+UplinkInterface=:self
+Announce=no
+#Assign=no
+
    +
  • /etc/system/systemd-networkd.service.d/10-debug.conf :
  • +
[Service]
+Environment=SYSTEMD_LOG_LEVEL=debug
+

note : since systemd v253, new options [EgressQOSMaps, IPServiceType, SocketPriority] exists to modify COS and DSCP to 6 on DHCPv4 (https://github.com/systemd/systemd/pull/25904).

WARNING : You always have to modify COS and DSCP for DHCPv6 (and ICMPv6). Todo this use the previous nftables rules (see paragraph).

dhcpcd (NetworkConfiguration)

noipv4ll
+nohook hostname resolv.conf timesyncd.conf
+allowinterfaces orange1
+debug
+logfile /var/log/dhcpcd.log
+noauthrequired
+noarp
+noipv6rs
+
+interface orange1
+	iaid	xxxxxxxx
+	ia_pd	xxxxxxxx br0//64
+	ipv6rs
+	clientid
+	userclass FSVDSL_livebox.Internet.softathome.Livebox6
+	vendclass 1038 sagem
+	vendorclassid sagem
+	broadcast
+	option subnet_mask routers domain_name_servers domain_name broadcast_address dhcp_lease_time dhcp_renewal_time dhcp_rebinding_time domain_search sip_server 125 auth
+	option dhcp6_vivso dhcp6_name_servers dhcp6_domain_search dhcp6_auth
+	nooption 33 57
+	authprotocol token 0x123/0x456
+	authtoken 0x456 "" forever 64:68:63:70:6c:69:76:65:62:6f:78:66:72:32:35:30
+	authtoken 0x123 "" forever 1a:09:00:00:05:58:01:03:41:01:0d:66:74:69:2f:...
+

dhclient

 WARNING : ISC dhclient is deprecated since 2023, prefer systemd-networkd

Do not forget to :

    +
  • +

    define Enter and Exit hooks

    +
  • +
  • +

    use so_priority or LD_PRELOAD to force packets COS6

    +
  • +
  • +

    if necessary and to avoid /etc/resolv.conf overwrite, use chattr +i /etc/resolv.conf

    +
  • +
  • +

    launch command lines :

    +
  • +
iface="orange1"
+cfgdir=...
+leasedir=...
+piddir=...
+dhclient -4 -cf ${cfgdir}/${iface}_4.conf -pf ${piddir}/${iface}_4.pid -lf ${leasedir}/${iface}_4.leases $iface 
+dhclient -6 -cf ${cfgdir}/${iface}_6.conf -pf ${piddir}/${iface}_6.pid -lf ${leasedir}/${iface}_6.leases -P -nw $iface
+
    +
  • /etc/dhclient/orange1_4.conf :
  • +
option rfc3118-authentication code 90 = string;
+interface "orange1" {
+  timeout 60;
+  retry 1;
+  select-timeout 0;
+  #supersede dhcp-renewal-time 30;
+  #supersede dhcp-rebinding-time 60;
+  #supersede dhcp-lease-time 90;
+  send vendor-class-identifier "sagem";
+  send user-class "+FSVDSL_livebox.Internet.softathome.Livebox4";
+  send rfc3118-authentication 00:00:00:00:00:00:<authentication_string>;
+  send dhcp-client-identifier 01:<livebox_mac>;
+  request subnet-mask, routers, broadcast-address;
+  #request subnet-mask, routers, domain-name-servers, domain-name, broadcast-address, dhcp-lease-time, dhcp-renewal-time, dhcp-rebinding-time, rfc3118-authentication;
+  #request subnet-mask, broadcast-address, dhcp-lease-time, dhcp-renewal-time, dhcp-rebinding-time, rfc3118-authentication;
+}
+
    +
  • /etc/dhclient/orange1_6.conf :
  • +
option dhcp6.auth code 11 = string;
+option dhcp6.userclass code 15 = string;
+option dhcp6.vendorclass code 16 = string;
+interface "orange1" {
+  timeout 60;
+  retry 1;
+  select-timeout 0;
+  send dhcp6.vendorclass 00:00:04:0e:00:05:73:61:67:65:6d;
+  send dhcp6.userclass 00:2b:46:53:56:44:53:4c:5f:6c:69:76:65:62:6f:78:2e:49:6e:74:65:72:6e:65:74:2e:73:6f:66:74:61:74:68:6f:6d:65:2e:4c:69:76:65:62:6f:78:34;
+  send dhcp6.auth 00:00:00:00:00:00:00:00:<authentication_string>;
+  send dhcp6.client-id 00:03:00:01:<livebox_mac>;
+  also request dhcp6.auth, dhcp6.vendorclass, dhcp6.userclass, dhcp6.vendor-opts;
+}
+

so_priority (LD_PRELOAD)

This utility must be used with dhcp client utility (like dhclient or dhpcd, NOT systemd). It provide the ability to run the dhcp client with a modified Socket Priority.
+WARNING : It is NOT compatible with systemd-networkd (which have built-in params to do COS6) ! 

compilation :

gcc -shared -ldl -fPIC so_priority.c -o so_priority.so
+

usage :

SO_PRIORITY_DEBUG=1 SO_PRIORITY_VALUE=6 LD_PRELOAD=/path/to/so_priority.so program arg1 arg2
+

source code :

/*
+        Set SO_PRIORITY right after each socket() call.
+        Compile with: gcc -shared -ldl -fPIC so_priority.c -o so_priority.so
+        Usage: SO_PRIORITY_DEBUG=1 SO_PRIORITY_VALUE=6 LD_PRELOAD=/path/to/so_priority.so program arg1 arg2
+
+        (c) 2020 - Xavier Guerrin
+        This program is free software. It comes without any warranty, to
+        the extent permitted by applicable law. You can redistribute it
+        and/or modify it under the terms of the Do What The Fuck You Want
+        To Public License, Version 2, as published by Sam Hocevar. See
+        http://www.wtfpl.net/ for more details.
+*/
+
+#define _GNU_SOURCE /* RTLD_NEXT */
+#include <dlfcn.h> /* dlsym, dlerror */
+#include <errno.h> /* errno */
+#include <stdio.h> /* dprintf */
+#include <stdlib.h> /* atoi, getenv */
+#include <string.h> /* strerror */
+#include <sys/types.h> /* setsockopt */
+#include <sys/socket.h> /* setsockopt */
+
+#ifndef SOPRIORITY_SO_NAME
+#define SOPRIORITY_SO_NAME "so_priority.so"
+#endif
+#ifndef SOPRIORITY_VALUE_EV
+#define SOPRIORITY_VALUE_EV "SO_PRIORITY_VALUE"
+#endif
+#ifndef SOPRIORITY_DEBUG_EV
+#define SOPRIORITY_DEBUG_EV "SO_PRIORITY_DEBUG"
+#endif
+
+typedef int (*socket_function_type)(int, int, int);
+
+/* Pointer to the actual socket symbol. */
+socket_function_type so_priority_socket = NULL;
+
+/* SO_PRIORITY value to set; can be configured using the SO_PRIORITY_VALUE environment variable. */
+int so_priority_value = 0;
+/* Debug level; can be configured using the SO_PRIORITY_DEBUG environment variable. */
+int so_priority_debug = 0;
+int so_priority_known = 0;
+
+/* Ask the linker to provide the actual "socket" symbol: */
+static int so_priority_get_socket() {
+        char *error_string;
+        so_priority_socket = (socket_function_type)dlsym(RTLD_NEXT, "socket");
+        if (!so_priority_socket) {
+                error_string = dlerror();
+                if (error_string) {
+                        dprintf(2, "%s: unable to find the actual socket symbol: %s\n", SOPRIORITY_SO_NAME, error_string);
+                }
+                else {
+                        dprintf(2, "%s: unable to find the actual socket symbol\n", SOPRIORITY_SO_NAME);
+                }
+                return 0;
+        }
+        return 1;
+}
+
+/* Read the priority value from the environment. */
+static void so_priority_set_options() {
+        char *str;
+        str = getenv(SOPRIORITY_VALUE_EV);
+        if (str) so_priority_value = atoi(str);
+        str = getenv(SOPRIORITY_DEBUG_EV);
+        if (str) so_priority_debug = atoi(str);
+        so_priority_known = 1;
+}
+
+/* Wrapper around the actual socket() function that sets SO_PRIORITY by calling setsockopt(). */
+int socket(int domain, int type, int protocol) {
+        int ret, setsockopt_errno, socket_errno, sockfd;
+
+        if (!so_priority_socket && !so_priority_get_socket()) {
+                errno = ENOENT;
+                return -1;
+        }
+        /* Actually call socket(): */
+        sockfd = so_priority_socket(domain, type, protocol);
+        /* Do not call setsockopt() if socket() failed: */
+        if (sockfd < 0) return sockfd;
+    
+        /* Time for the actual work: */
+        socket_errno = errno;
+    
+        if (!so_priority_known) so_priority_set_options();
+        ret = setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &so_priority_value, sizeof(so_priority_value));
+        /* Ignore setsockopt() errors, except for debugging purposes. */
+        if (so_priority_debug) {
+                setsockopt_errno = errno;
+                dprintf(2, "%s: setsockopt(%d, SOL_SOCKET, SO_PRIORITY, %d, %zu) returned %d",
+                        SOPRIORITY_SO_NAME, sockfd, so_priority_value, sizeof(so_priority_value), ret);
+                if (ret < 0) dprintf(2, "; errno is %d: %s", setsockopt_errno, strerror(setsockopt_errno));
+                dprintf(2, "\n");
+        }
+    
+        errno = socket_errno;
+        return sockfd;
+}
+

Archlinux PKGBUILD :

# https://git.kindwolf.org/so_priority.so/
+# https://lafibre.info/remplacer-livebox/petit-ld_preload-pour-amateurs-de-setsockopt/
+# USAGE : SO_PRIORITY_DEBUG=1 SO_PRIORITY_VALUE=6 LD_PRELOAD=/path/to/so_priority.so program arg1 arg2
+
+pkgname=so_priority
+pkgver=1.0
+pkgrel=0
+
+pkgdesc='Set SO_PRIORITY (aka skb->priority) right after each socket() call.'
+arch=('i686' 'x86_64')
+url="https://git.kindwolf.org/so_priority.so"
+license=('GPL3')
+
+source=(https://git.kindwolf.org/so_priority.so/raw/master/so_priority.c)
+
+validpgpkeys=(
+        'SKIP'
+)
+sha256sums=(
+        'SKIP')
+
+build() {
+        cd "$srcdir"/
+        gcc -shared -ldl -fPIC so_priority.c -o so_priority.so
+}
+
+package() {
+        cd "$srcdir"/
+        for s in *.so; do
+                install -Dm755 $s "$pkgdir/usr/lib/so_priority/$s"
+        done
+}
+

Debug & Troubleshoot

    +
  • +

    If you get no answer from Orange DHCP server and everything seems to be ok, try to force release multiple times and disconnect a few minutes the ONT (fiber link) to force DHCP lease expiration.

    +
  • +
  • +

    In some case, you just have to remove dhcp client lease file (see relative documentation of each dhcp client).

    +
  • +
  • +

    Sometimes, when switching hardware or interface on the same fiber link, you will encounter IAID issue. In this case the DHCPv6 server (ISP) will give NO PREFIX answer. You have to disconnect fiber link for at least 10-20min. Then reconnect and retry DHCP requests. You should have no issue with DHCPv4. Check also option 17 (vendor_opt) answer, if everything is correct, try again to disconnect fiber link for a few minutes.

    +
  • +
  • +

    Finally try to regenerate authentication options (90 for DHCPv4 and 11 for DHCPv6). Sometimes, it could be necessary to regenerate authentication options, after a few months for example...

    +
  • +
  • +

    For COS 6 verification check the first line tcpdump trace, check :

    +
  • +
'[vlan ${vlan}, p X]' : ..., ethertype 802.1Q (0x8100), length XXX: vlan ${vlan}, p X, ethertype IPv4 (0x0800), ...
+

tcpdump command lines :

# prefer :
+tcpdump -vnei wan1 '(udp port 546 or port 547) or icmp6'
+# alternatives :
+tcpdump -i wan1 -ne -vv "(udp port 546 and port 547)"
+tcpdump -i wan1 -vvv -n ip6  “(udp port 546 and port 547)”
+tcpdump -vnes0 -i wan1 udp port 67 or port 68 or port 546 or port 547
+tcpdump -vvvvv -ttt -i wan1 'icmp6 and (ip6[40] = 134 or ip6[40] = 133 or ip6[40] = 135 or ip6[40] = 136 or ip6[40] = 129 or ip6[40] = 128 or ip6[40] = 3 or ip6[40] = 2 or ip6[40] = 1)' -w /tmp/capture.pcap # use wireshark to analyse /tmp/capture.pcap
+
    +
  • +

    For DHCP response :
    +https://lafibre.info/remplacer-livebox/durcissement-du-controle-de-loption-9011-et-de-la-conformite-protocolaire/24/
    +In DHCP response, there is an option (DHCPv4 [125] et DHCPv6 [17|vendor_opts_]) in return with 2 bytes information : 000100XXXX ffffffffff

    +
  • +
  • +

    00xx : OK, everything is fine

    +
  • +
  • +

    01xx : box model, firmware or line issue (0102:too aggressive requests, 0199:bad COS)

    +
  • +
  • +

    02xx : bad login/password (or encoding)

    +
  • +
  • +

    03xx : account already unregistered

    +
  • +
  • +

    04xx : billing issue

    +
  • +
  • +

    If your connection is up and running, BUT (after some times) your download/upload speed is SLOW, it should be related to a QOS issue :
    +The standard flow (everything except DHCP related traffic) QOS MUST be 0 (zero)
    +Everything related to DHCP (DHCPv4/6 init|renew ; ICMPv6 ; ARP) QOS MUST be 6 (six)

    +
  • +

Systemd-networkd

    +
  • use DUIDType=link-layer
  • +
  • from tcpdump : client-ID hwaddr 44d4540axxxx ; IA_PD-prefix 2a01:cb15:3e4:xxxx::/56 ; IA_PD IAID:22882960xx
  • +
  • check interface status : networkctl status <iface>
  • +

DHCP6 Client IAID: 0x8864a065
+DHCP6 Client DUID: DUID-LL:000144d4540axxxx0000

tcpdump sample trace :

dhcp6 solicit   (xid=6461b1 (rapid-commit) (IA_PD IAID:22882960xx T1:0 T2:0) (Client-FQDN) (user-class) (option-request opt_82) (client-ID hwaddr type 1 44d4540axxxx)
+dhcp6 advertise (xid=6461b1 (IA_PD IAID:22882960xx T1:83812 T2:207360 (IA_PD-prefix 2a01:cb15:3e4:xxxx::/56 pltime:259200 vltime:259200)) (server-ID vid 0000055844455348) (client-ID hwaddr type 1 44d4540axxxx)
+dhcp6 request   (xid=76595c (server-ID vid 0000055844455348) (IA_PD IAID:22882960xx T1:0 T2:0 (IA_PD-prefix 2a01:cb15:3e4:xxxx::/56 pltime:0 vltime:0)) (Client-FQDN) (user-class) (client-ID hwaddr type 1 44d4540axxxx)
+dhcp6 reply     (xid=76595c (IA_PD IAID:22882960xx T1:86413 T2:207360 (IA_PD-prefix 2a01:cb15:3e4:xxxx::/56 pltime:259200 vltime:259200)) (server-ID vid 0000055844455348) (client-ID hwaddr type 1 44d4540axxxx)
+

Mikrotik (RouterOS)

Sometimes, when switching hardware or interface on the same fiber link, you will encounter IAID issue. In this case ipv6 DHCP client will give you NO PREFIX answer from DHCP server.
+https://wiki.mikrotik.com/wiki/Manual:IPv6/DHCP_Client
+To determine what IAID will be used, convert internal ID of an interface on which DHCP client is running from hex to decimal. For example, DHCP client is running on interface pppoe-out1. To get internal ID use following command :
+/interface> :put \[find name="vlan832-orange1"]
+For example, you will get : *15
+Now convert hex value 15 to decimal and you get IAID=21

routerOS command line to snif interface and send to a remote host :

xxxxxx] > /tool/sniffer/export 
+# apr/20/2023 19:01:18 by RouterOS 7.6
+# software id = xxxxxx
+#
+# model = CCR2004-1G-12S+2XS
+# serial number = xxxxxxx
+/tool sniffer
+set file-limit=100000KiB filter-interface=br-wan filter-ip-protocol=udp filter-port=bootps,bootpc,546,547 filter-stream=yes memory-limit=5000KiB memory-scroll=no streaming-enabled=yes streaming-server=192.168.xxx.xxx
+
\ No newline at end of file