Internode’s instructions for configuring IPv6 routing on linux are pretty terse, merely giving some suggestions for using WIDE DHCPv6 and radvd. On modern Linux with systemd, these extra daemons are unnecessary; all that’s required is
systemd-networkd. This post describes the problems and how I got dual-stack IPv4/IPv6 routing over Internode’s NBN service, using a Raspberry Pi running Debian Buster.
Firstly, here’s all the things we want the router to do:
- Create a PPPoE connection to Internode via the NBN (HFC).
- Establish the IPv6 address of the upstream router and create a default route there.
- Issue Router Advertisements (RA) to other hosts on the LAN so that they can configure their global IPv6 address and default route using SLAAC.
- Act as a DHCPv6 client for Prefix Delegation. It’s not obvious why this is required: Internode allocates a static /56 prefix, and I can statically configure my router to advertise that in its RA. However, it turns out that without the DHCP lease, upstream routes aren’t created for hosts in the /56 prefix!
Glen Turner has an excellent guide for a setup on Debian Wheezy consistent with Internode’s recommendation, using the
wide-dhcpv6-client packages. But on Debian Buster, this feels quite outdated: wide-dhcp6cd’s will exit immediately (rather than wait) if its config mentions an interface that doesn’t exist. Hence systemd disables it because of the fail-loop it enters on system boot when ppp0 doesn’t exist. On top of this, there’s no good logging level for wide-dhcp6cd; the “debug” level pours out minutiae of config-file parsing, while the merely “verbose” level gives no indication about what the DHCP replies contain. It’s also using a SysV-style init script rather than a modern systemd service.
I’ve also avoided using GNOME’s
NetworkManager, which I feel is too bloated for a headless router in a stable network topology.
My configs follow.
Continue reading “Internode IPv6 on Linux with systemd-networkd”
Update 2021-02-24: The Chrome developers have rolled back the change.
The latest stable Chrome (released February 4), breaks the way keywords can be used to invoke search engines from the omnibox (address bar). TLDR: typing space after the keyword no longer works, but tab does. Disabling the omnibox-keyword-search-button flag will revert to the old behaviour.
Prior to the upgrade I could type
g foo directly in the omnibox, hit enter, and get Google search results for “foo”. After typing the space after the “g”, the keyword gets expanded to “Search Google” or similar, so in the case of “g foo”, you actually see something like “Search Google | foo”.
This works because I configured Google search to use the “g” keyword, from the chrome://settings/searchEngines settings page, as documented by Google.
However, this stopped working in Chrome 88.0.4324.150. Instead of “g foo” invoking the search engine I’d configured with keyword “g”, it invoked the default search engine with the query “g foo”! This was extremely disconcerting since I’m very accustomed to using keyword prefixes to search different websites.
However, you can still get at the keyword search functionality by hitting tab after the keyword rather than space. So in the previous example, typing
foo will search for “foo”. The tab key doesn’t work quite the same way that space used to: it moves focus to a button in the autocomplete list for the keyword search, but merely having focus is enough to activate the search when you continue typing.
The Chrome search engine shortcuts no longer auto-fill with space bug on the Chromium tracker explains that this is due to the new button, and that you can get space working again by opening the chrome://flags/#omnibox-keyword-search-button settings and disabling the omnibox-keyword-search-button flag.
Conventional assessment of route difficulty for rock climbing is a subjective process. A small number of people (often just one) assign a grade for a particular route, and there isn’t really a process for refining grades once they’ve been assigned (it’s just one opinion vs another). Most of the grading systems are on an ordinal scale, which means you can rank the grades in order but the difference or ratio between grades isn’t meaningful. Intentional biases are even part of climbing culture.
To address these shortcomings, I developed a statistical model for grading rock climbing routes. The difficulty of a climbing route and the performance of a climber on a particular day are described by numerical ratings. The difference in ratings between a climber and a route determines the probability the climber will ascend the route “successfully”. For modern sport climbing, success loosely means getting to the top without weighting a rope or other mechanical devices. The climbing model is based on a dynamic Bradley-Terry model, which is a common model for game and sports rating systems such as Elo and Glicko-2.
While the statistical model provides a theory for predicting ascent outcomes based on ratings parameters, it’s not useful in practice without a process for estimating the parameters (individual ratings for climbers and routes) and hyperparameters (generalizations that are independent of individual climbers or routes, e.g. how hard the “average” route is, and how quickly climbers can improve). So I implemented an algorithm for estimating the parameters, based on the Whole-History Rating (WHR) algorithm. WHR is a fast algorithm that uses second-order (Newton-Raphson) optimization for finding the ratings for climbers and routes that maximize the likelihood of observing a particular set of ascents (known as the maximum a posteriori estimates). I used machine learning methods to choose the hyperparameters. The implementation is available as a free, open-source software package at the Climbing Ratings project on GitHub.
Continue reading “Machine learning for climbing grades”