kernelkit / infix

Linux :yellow_heart: NETCONF = Infix
https://kernelkit.org
GNU General Public License v2.0
46 stars 12 forks source link

update hostname with udhcpc script #278

Closed minexn closed 7 months ago

minexn commented 8 months ago

I do not see any hostnames assigned to the test infix clients connected to my router.

We are not sending the hostname in the udhcpc script.

-x hostname:infix-host

The test below works.

bash-5.2# udhcpc -i eth1 -x hostname:infix-host 
udhcpc: started, v1.36.0
udhcpc: broadcasting discover
udhcpc: broadcasting select for 10.10.3.216, server 10.10.3.1
udhcpc: lease of 10.10.3.216 obtained from 10.10.3.1, lease time 600
troglobit commented 8 months ago

This is actually by design, at least up until now. The primary target for Infix (currently) is switches with multiple VLANs, and since we support multiple DHCP clients it did not make sense to allow setting the hostname via DHCP. It's a singleton, so what should we do if multiple clients try to set the name, who wins?

What we do, however, is send the current hostname to the DHCP server in case it wants to register it with the DNS server, a dnsmasq based DHCP server does this, for instance.

Is this a hard requirement for your devices to support?

(ping @wkz)

minexn commented 8 months ago

It would be great to have both DHCP client and server support, but I see how our paths might be heading in a different direction. We would like to use Infix as the base for a routing platform.

We were trying to determine why the device doesn't get an assigned IP address on boot.

admin@infix-2b-d5-d4:~$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether ea:b1:0e:3c:f2:01 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::e8b1:eff:fe3c:f201/64 scope link dadfailed tentative proto kernel_ll 
       valid_lft forever preferred_lft forever

The DHCP client is working

admin@infix-2b-d5-d4:~$ ps | grep dhcp
  532 root      0:00 udhcpc -f -p /run/dhcp-eth0.pid -t 10 -T 3 -A 10 -a1000 -S -R -o -O router -O dns -O domain -O broadcast -O ntpsrv -O search -r 10.10.3.227 -O staticroutes -O msstaticroutes -i eth0 -V Infix v23.11.0-110-g641d328

Manual request

admin@infix-2b-d5-d4:~$ sudo udhcpc eth0
udhcpc: started, v1.36.0
udhcpc: broadcasting discover
udhcpc: broadcasting select for 10.10.3.228, server 10.10.3.1
udhcpc: lease of 10.10.3.228 obtained from 10.10.3.1, lease time 600

Device is now connected

admin@infix-2b-d5-d4:~$ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether ea:b1:0e:3c:f2:01 brd ff:ff:ff:ff:ff:ff
    inet 10.10.3.228/24 scope global proto dhcp eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::e8b1:eff:fe3c:f201/64 scope link dadfailed tentative proto kernel_ll 
       valid_lft forever preferred_lft forever

Any idea why we're not getting an IP address on boot?

Jan 22 11:06:03 infix-2b-d5-d4 udhcpc[542]: started, v1.36.0 
Jan 22 11:06:03 infix-2b-d5-d4 finit[1]: Starting dhcp:eth0[542]
Jan 22 11:06:03 infix-2b-d5-d4 udhcpc[543]: action deconfig
Jan 22 11:06:03 infix-2b-d5-d4 udhcpc[543]: deleting DHCP routes from eth0
Jan 22 11:06:03 infix-2b-d5-d4 udhcpc[542]: broadcasting discover 
Jan 22 11:06:03 infix-2b-d5-d4 udhcpc[542]: broadcasting select for 10.10.3.228, server 10.10.3.1 
Jan 22 11:06:03 infix-2b-d5-d4 udhcpc[542]: lease of 10.10.3.228 obtained from 10.10.3.1, lease time 600 
Jan 22 11:06:03 infix-2b-d5-d4 kernel: IPv6: eth0: IPv6 duplicate address fe80::e8b1:eff:fe3c:f201 used by ea:b1:0e:3c:f2:01 detected!
Jan 22 11:06:04 infix-2b-d5-d4 udhcpc[555]: action bound
Jan 22 11:06:04 infix-2b-d5-d4 udhcpc[555]: deleting DHCP routes from eth0
Jan 22 11:06:04 infix-2b-d5-d4 udhcpc[555]: adding dns 10.10.3.1
Jan 22 11:06:04 infix-2b-d5-d4 dnsmasq[352]: reading /var/lib/misc/resolv.conf
Jan 22 11:06:04 infix-2b-d5-d4 dnsmasq[352]: using nameserver 10.10.3.1#53
Jan 22 11:06:04 infix-2b-d5-d4 dnsmasq[352]: read /etc/hosts - 2 names
Jan 22 11:06:04 infix-2b-d5-d4 dnsmasq[352]: setting upstream servers from DBus
Jan 22 11:06:04 infix-2b-d5-d4 dnsmasq[352]: using nameserver 10.10.3.1#53
Jan 22 11:06:04 infix-2b-d5-d4 dnsmasq[352]: read /etc/hosts - 2 names

Strangely enough, it only happens with my Mikrotik router; the device gets an IP address on my PfSense gateway.

minexn commented 8 months ago

This is the result of the PfSense DHCP request.

Jan 21 11:50:18 infix-r2s-x kernel: rk_gmac-dwmac ff540000.ethernet eth0: Link is Up - 1Gbps/Full - flow control off
Jan 21 11:50:18 infix-r2s-x udhcpc[535]: started, v1.36.0 
Jan 21 11:50:18 infix-r2s-x udhcpc[536]: action deconfig
Jan 21 11:50:18 infix-r2s-x finit[1]: Starting dhcp:eth0[535]
Jan 21 11:50:18 infix-r2s-x udhcpc[536]: deleting DHCP routes from eth0
Jan 21 11:50:18 infix-r2s-x udhcpc[535]: broadcasting discover 
Jan 21 11:50:21 infix-r2s-x udhcpc[535]: broadcasting discover 
Jan 21 11:50:25 infix-r2s-x last message buffered 1 times
Jan 21 11:50:25 infix-r2s-x udhcpc[535]: broadcasting select for 10.10.1.208, server 10.10.1.1 
Jan 21 11:50:25 infix-r2s-x udhcpc[535]: lease of 10.10.1.208 obtained from 10.10.1.1, lease time 7200 
Jan 21 11:50:26 infix-r2s-x udhcpc[548]: action bound
Jan 21 11:50:26 infix-r2s-x udhcpc[548]: deleting DHCP routes from eth0
Jan 21 11:50:26 infix-r2s-x udhcpc[548]: adding search asynix.com
Jan 21 11:50:26 infix-r2s-x udhcpc[548]: adding dns 10.10.2.5
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: reading /var/lib/misc/resolv.conf
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.5#53
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: read /etc/hosts - 2 names
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: setting upstream servers from DBus
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.5#53
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.5#53 for domain xxx
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: read /etc/hosts - 2 names
Jan 21 11:50:26 infix-r2s-x udhcpc[548]: adding dns 10.10.2.6
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: reading /var/lib/misc/resolv.conf
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.5#53 for domain xxx
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.5#53
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.6#53
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: read /etc/hosts - 2 names
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: setting upstream servers from DBus
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.5#53
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.6#53
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.5#53 for domain xxx 
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: using nameserver 10.10.2.6#53 for domain xxx
Jan 21 11:50:26 infix-r2s-x dnsmasq[353]: read /etc/hosts - 2 names
troglobit commented 8 months ago

I talked it over with a few colleagues, we decided we can open up setting hostname via dhcp client and leave it to the user to enable option 12 only for the client that should set the hostname. There would however not be any locks preventing a static hostname (via NETCONF) to override it.

We will be adding DHCP server support too, but later. Likely during Q3-04.

The problem with DHCP lease from Mikrotik is really difficult to answer, also did not fully understand: did you get a lease from it if you retry manually after boot? The DHCP client forks to the background and retries with a backoff timer, so it should definitely get a lease later. Dunno, but maybe the Mikrotik has spanning tree enabled by default, if so it may take up to 30 seconds for access ports on it to go to forwarding.

Another reason for problems could the default set of DHCP options we send with the client (configurable using the CLI/NETCONF), if the DHCP server on the Mikrotik doesn't like/accept one or more options it may discard the request entirely, and when you call udhcpc manually you don't provide our default options and the server happily replies? Just speculating, would be better if you check the wireshark logs between the server and client, it could be a NAK or sth that we don't see in the logs.

minexn commented 7 months ago

udhcpc is reporting "Error: any valid prefix is expected rather than 10.10.3.228/." when connecting to the Mikrotik.

I removed the -o option from infix-dhcp.c, and it now connects perfectly.

__

        fprintf(fp, "service <!> name:dhcp :%s <net/%s/running> \\\n"
                "       [2345] udhcpc -f -p /run/dhcp-%s.pid -t 10 -T 3 -A 10 %s -S -R \\\n"
                "               %s \\\n"

PFsense reply

Dynamic Host Configuration Protocol (ACK)
    Message type: Boot Reply (2)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0x976dc715
    Seconds elapsed: 0
    Bootp flags: 0x0000 (Unicast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 10.10.2.217
    Next server IP address: 0.0.0.0
    Relay agent IP address: 0.0.0.0
    Client MAC address: ea:b1:0e:3c:f2:01 (ea:b1:0e:3c:f2:01)
    Client hardware address padding: 00000000000000000000
    Server host name not given
    Boot file name not given
    Magic cookie: DHCP
    Option: (53) DHCP Message Type (ACK)
    Option: (1) Subnet Mask (255.255.255.0)
    Option: (3) Router
    Option: (6) Domain Name Server
    Option: (12) Host Name
    Option: (15) Domain Name
    Option: (51) IP Address Lease Time
    Option: (54) DHCP Server Identifier (10.10.2.1)
    Option: (255) End

Original Mikrotik reply

Dynamic Host Configuration Protocol (ACK)
    Message type: Boot Reply (2)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0x09c73d7b
    Seconds elapsed: 0
    Bootp flags: 0x0000 (Unicast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 10.10.3.228
    Next server IP address: 10.10.3.1
    Relay agent IP address: 0.0.0.0
    Client MAC address: ea:b1:0e:3c:f2:01 (ea:b1:0e:3c:f2:01)
    Client hardware address padding: 00000000000000000000
    Server host name not given
    Boot file name not given
    Magic cookie: DHCP
    Option: (53) DHCP Message Type (ACK)
    Option: (51) IP Address Lease Time
    Option: (54) DHCP Server Identifier (10.10.3.1)
    Option: (255) End
    Padding: 000000000000000000000000000000000000000000000000000000000000000000000000…
minexn commented 7 months ago

Do we need the -o option?

Mikrotik reply without the -o option


Dynamic Host Configuration Protocol (ACK)
    Message type: Boot Reply (2)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0x76846e04
    Seconds elapsed: 0
    Bootp flags: 0x0000 (Unicast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 10.10.3.228
    Next server IP address: 10.10.3.1
    Relay agent IP address: 0.0.0.0
    Client MAC address: ea:b1:0e:3c:f2:01 (ea:b1:0e:3c:f2:01)
    Client hardware address padding: 00000000000000000000
    Server host name not given
    Boot file name not given
    Magic cookie: DHCP
    Option: (53) DHCP Message Type (ACK)
    Option: (1) Subnet Mask (255.255.255.0)
    Option: (3) Router
    Option: (6) Domain Name Server
    Option: (51) IP Address Lease Time
    Option: (54) DHCP Server Identifier (10.10.3.1)
    Option: (255) End
    Padding: 0000000000000000000000000000000000000000000000000000
troglobit commented 7 months ago

udhcpc is reporting "Error: any valid prefix is expected rather than 10.10.3.228/." when connecting to the Mikrotik.

Ouch, that looks like a bug in our udhcpc script! It should not assume getting a cidr prefix.

I removed the -o option from infix-dhcp.c, and it now connects perfectly.

I suspected as much, there's probably one or more options we send by default that trips up the MikroTik. (In addition to what looks like a bug in our script, above.)

The -o options are which DHCP options we request and accept from the server. A conformant server should ignore options it doesn't support and reply with the ones it does. If the server replies with more options than we accept then the udhcpc script makes sure to not set them.

I suggest trying with a subset of options, for example:

admin@infix-00-00-00:/> configure 
admin@infix-00-00-00:/config/> edit dhcp-client client-if e0 
admin@infix-00-00-00:/config/dhcp-client/client-if/e0/> set 
           arping        client-id          enabled           option route-preference
admin@infix-00-00-00:/config/dhcp-client/client-if/e0/> set option                     # Pressing '?' key
  <string>        DHCP option to request from, or inform server of.
  address         Requested (previously cached) address
  broadcast       Broadcast address
  clientid        Client ID (default MAC, and option 12)
  dns             DNS server
  domain          Domain name
  fqdn            Request DNS update of client FQDN argument
  hostname        Hostname
  msstaticroutes  Microsoft classless static routes
  ntpsrv          NTP server
  router          Default route(s)
  search          Domain search list
  staticroutes    Classless static routes
  subnet          Subnet (IP address and netmask)
admin@infix-00-00-00:/config/dhcp-client/client-if/e0/> set option address 
admin@infix-00-00-00:/config/dhcp-client/client-if/e0/> set option broadcast 
admin@infix-00-00-00:/config/dhcp-client/client-if/e0/> set option dns
admin@infix-00-00-00:/config/dhcp-client/client-if/e0/> set option router
admin@infix-00-00-00:/config/dhcp-client/client-if/e0/> set option subnet 
admin@infix-00-00-00:/config/dhcp-client/client-if/e0/> show
option address
option broadcast
option dns
option router
option subnet
admin@infix-00-00-00:/config/dhcp-client/client-if/e0/> leave
admin@infix-00-00-00:/> copy running-config startup-config
admin@infix-00-00-00:/> 

When you find a subset that works we can have a look and see if should change the built-in default of Infix :-)


Edit: Err, I should read your report more carefully. Thankfully @wkz talked to me just now and pointed out the difference between -o and -O ... so:

  1. we still have that naive bug in the udhcpc script
  2. it seems RouterOS is doing what we tell it to do, i.e., send no options

The idea with using -o is to disable all the default options the DHCP client requests and have a safe default set of options be inferred when enabling DHCP client on an interface. That way the user could opt-out of requesting options that are otherwise hard-coded in udhcpc. The inference of options is an omission in the implementation, and I'll have a look at it as soon as possible.

As per your last listing, options 1, 3, and 6, seem like obvious candidates.

Sorry for the confusion on my part.

minexn commented 7 months ago

Everything works perfectly - thank you!