On 19.11.2012 19:39, Oleksii Tsvietnov wrote:
On 11/19/2012 05:10 PM, Vadim S. Goncharov wrote:
Можно прямо сейчас костылями: создается фейковый адрес шлюза,
например, 1.1.1.254, с тем же MAC-адресом, что и реальный 1.1.1.1, далее:
ipfw fwd 1.1.1.254 all from 1.1.1.16 to not $service_net out xmit ext0

Т.е. создать статическую привязку в ARP-таблице и статичекий маршрут для
1.1.1.254 через ext1 ?

Да, чтобы fwd знал, на какой MAС-адрес отправлять. На самом деле чуть сложнее - маршрут на ext1 должен еще и в ext1 смотреть, помимо про L2-адреса. Можно и не из той же сети 1.1.1.0/24, а просто что угодно с маршрутом в эту карту и нужным L2-адресом.

Если хочется потестировать и предложить разработчикам улучшить, можно попробовать способ "как у белых людей" (а-ля iproute2 в Linux): создаются 2 таблицы маршрутизации (setfib), в каждой описывается этот шлюз как есть на самом деле (только смотрящий в тот или иной интерфейс); все входные пакеты на каждом интерфейсе помечаются принадлежащими соответствующей таблице маршрутизации с помощью ifconfig fib N. Патч делает так, чтобы эта информация не терялась, а применялась ко всем последующим ответам на соединение.

Для использования нужно приложить патч, стоя в /sys (не знаю, какая версия, сделал для 8.1, накладывается и на 9.0), и пересобрать ядро (не забыв указать в конфиге поддержку нескольких таблиц маршрутизации).

--
Vadim Goncharov     <[email protected]>           RU-Center
NET Department                            http://www.nic.ru
NET-SYS Group             phone:+7(495)737-7646  (ext.4019)
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 240698)
+++ netinet/tcp_input.c (working copy)
@@ -754,9 +754,16 @@ relocked:
                }
                inc.inc_fport = th->th_sport;
                inc.inc_lport = th->th_dport;
-               inc.inc_fibnum = so->so_fibnum;
 
                /*
+                * If application doesn't care to explicitly set FIB on
+                * socket, inherit FIB of initial packet (for PBR).
+                *
+                * XXX doesn't work with TCP Offload
+                */
+               inc.inc_fibnum = so->so_fibnum ? so->so_fibnum : M_GETFIB(m);
+
+               /*
                 * Check for an existing connection attempt in syncache if
                 * the flag is only ACK.  A successful lookup creates a new
                 * socket appended to the listen queue in SYN_RECEIVED state.
Index: netinet/tcp_syncache.c
===================================================================
--- netinet/tcp_syncache.c      (revision 240698)
+++ netinet/tcp_syncache.c      (working copy)
@@ -657,6 +657,12 @@ syncache_socket(struct syncache *sc, struct socket
        mac_socketpeer_set_from_mbuf(m, so);
 #endif
 
+       /*
+        * If application doesn't care to explicitly set FIB on
+        * socket, inherit FIB of initial packet (for PBR).
+        */
+       so->so_fibnum = so->so_fibnum ? so->so_fibnum : sc->sc_inc.inc_fibnum;
+
        inp = sotoinpcb(so);
        inp->inp_inc.inc_fibnum = so->so_fibnum;
        INP_WLOCK(inp);

Ответить