iptables дергает API ядра (netfilter) и создает правила, по которым работают ядерные модули. На каждый протокол чих есть соответствующий ядреный модуль - например, если хочешь фильтровать по диапазону портов, нужен модуль xt_multiport. Если модуль есть - он загружается автоматически. если нет - печаль (
Некоторое время назад разработчиков достала необходимость писать кучу модулей и они сделали nftables. Он устроен по-другому: на уровне ядра есть конечный автомат, который исполняет байт-код и с помощью этого байт-кода фильтрует пакеты. Пользовательская утилита просто компилирует правила в байт-код и загружает его в ядро.