Назначение двух различных функций в «dst_entry» («ввод» и «вывод») в версии 5 ядра Linux

#networking #routes #linux-kernel

Вопрос:

Если я правильно понял, то в предыдущих версиях ядра Linux (например, в версии 2) есть два различных указателей функций В dst_entry (а именно: input а output ) для того, чтобы обеспечить следующий сценарий (возможно, были некоторые другие сценарии, которые требуют этого): во время «выхода» из IP-пакета, определяется как предназначенные для текущего хоста, output имеет значение ip_output и input имеет значение ip_local_deliver . Причина input , установленная в этом сценарии, заключается в том, что мы знаем, что пакет будет «доставлен нам обратно», и на пути «входа» у нас теперь будет rtable запись уже кэширована, и мы можем напрямую вызвать указатель input функции. Правильно ли я это понял?

Однако, из того, что я мог видеть, в текущей версии ядра Linux (5) существуют разные записи кэша для пути «выход» и «вход» (т. Е. Запись кэша, установленная во время пути «выход», будет получена только во время будущего пути «выход», и то же самое для пути «вход»). Эти записи nhc_pcpu_rth_output (для «выхода») и nhc_rth_input (для «входа») находятся внутри fib_nh_common .

Скорее всего, есть сценарий, которого мне не хватает, который включает в себя настройку output функции во время «входа», а затем ее использование в будущем во время пути «выхода» или наоборот.

Я был бы очень признателен, если бы кто-нибудь мог указать причину наличия двух разных указателей функций внутри dst_entry ( input и output ) в текущей версии ядра Linux.

Спасибо.

Комментарии:

1. @JustinIurman Благодарю вас за ваш ответ. Я прочитал код больше и подумал о двух сценариях, в которых требуется установить оба input и output на одном и том же dst_entry . Первый сценарий, перенаправление пакетов : IP-пакет поступает на интерфейс; маршрутизация определяет, что он не предназначен для этого хоста, поэтому его необходимо перенаправить; input устанавливается ip_forward и output устанавливается ip_output ( ip_forward в конечном итоге вызовет output ). Второй сценарий, отправка пакета на текущий хост : output установлен ip_output и input установлен ip_local_deliver . [продолжение]

2. Когда пакет «возвращается» из интерфейса обратной связи, в нем уже dst заполнена структура (проверка выполняется внутри ip_input.c , внутри ip_rcv_finish_core : if (!skb_valid_dst(skb)) ... , поэтому input функцию можно вызвать без необходимости повторять весь процесс маршрутизации. Правильно ли я теперь это понимаю?

3. Ваш первый сценарий верен, а не ваш второй. Действительно, между ними нет никакой разницы. На самом деле, когда пакет предназначен для локального хоста, input будет установлено значение ip6_input (я возьму IPv6 в качестве примера, потому что я более знаком с ним, но он должен быть очень похож на IPv4) и output не будет использоваться, так как в этом случае он бесполезен. В качестве резюме, когда пакет будет отправлен хосту, input будет ip6_input (который затем вызовет ip6_protocol_deliver_rcu ). Если пакет не для хоста, input будет ip6_forward и output будет ip6_output .

4. @JustinIurman Еще раз спасибо вам за ваш ответ! Извините, мне следовало быть более конкретным. Для моего второго сценария, отправки пакета на текущий хост , я имел в виду ситуацию, в которой один хост отправляет пакет самому себе (например, он отправляет пакет на 127.0.0.1, в случае, если это адрес интерфейса обратной связи). Учитывая это уточнение, является ли поток, который я описал, правильным?

5. Хммм, я понимаю. Ну, вероятно, это происходит не так, как вы описали, хотя я не уверен, где в коде это обрабатывается. Дело в том, что пакет не будет покидать и повторно входить в ваш узел, поскольку адрес назначения является обратной связью, он будет доставлен напрямую (опять же, есть что-то на output стороне, чтобы решить эту проблему, но input здесь это не играет роли). На самом деле, input никогда не вступает в игру, когда речь идет о пакетах, отправленных с вашего узла. Самое близкое к вашим рассуждениям, о чем я мог подумать, это то, что пакет будет повторно введен в сетевой стек, а затем input будет установлен.