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);