user@localhost:~$ ip addr show wlan0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 4c:33:22:11:aa:ee brd ff:ff:ff:ff:ff:ff
inet 192.168.133.50/24 brd 192.168.133.255 scope global wlan0
valid_lft forever preferred_lft forever
inet6 2001:e68:5424:d2dd:4e33:22ff:fe11:aaee/64 scope global dynamic
valid_lft 86399sec preferred_lft 14399sec
inet6 fe80::4e33:22ff:fe11:aaee/64 scope link
valid_lft forever preferred_lft forever
So first, what is Link-local address?
In a computer network, a link-local address is a network address that is valid only for communications within the network segment (link) or the broadcast domain that the host is connected to.
Link-local addresses are usually not guaranteed to be unique beyond a single network segment. Routers therefore do not forward packets with link-local addresses.
For protocols that have only link-local addresses, such as Ethernet, hardware addresses that the manufacturer delivers in network circuits are unique, consisting of a vendor identification and a serial identifier.
Link-local addresses for IPv4 are defined in the address block 169.254.0.0/16, in CIDR notation. In IPv6, they are assigned with the fe80::/10 prefix.
So it is a wire address that is locally within a segment of a network and it is not routable beyond a router.
With this said, let's calculate link-local address.
1. take the mac address from ip command.
from above example 4c:33:22:11:aa:ee
2. add ff:fe in the middle of the current mac address.
4c:33:22:ff:fe:11:aa:ee
3. reformat to IPv6 notation by concatenate two hex groups into one.
4c33:22ff:fe11:aaee
4. convert the first octet from hexadecimal to binary
4c -> 01001100
5. invert the bit at position 6, starting from left with first bit as 0.
01001100 -> 01001110
6. convert the octet back in step 5 back to hexadecimal
01001110 -> 4e
7. replace first octet with newly calculated from step 6.
4e33:22ff:fe11:aaee
8. prepend the link-local prefix
fe80::4e33:22ff:fe11:aaee
That's it.