# ppp-интерфейсы и маршруты

## nilreM

Добрый вечер.

Имеется система на базе Gentoo, ветка x86 (стабильная), настроенная как роутер с двумя провайдерами и локалкой. Соответственно, воткнуто три сетевых платы. Провайдеры подключаются: один из - через pptp, второй - через pppoe через asdl-модем, настроенный как bridge.

Естественно, задумывалось всё это как интернет с резервированием и оптимальной маршрутизацией. Для каждого провайдера известны его сети, в которые нужно ходить именно через него, а не через шлюз по умолчанию. Для всего остального настроен split access по lartc. Было бы очень хорошо управиться исключительно посредством инит-скриптов Gentoo, без привлечения каких-то внешних cron-заданий или чего-то ещё неочевидного.

Первый вопрос такой. Используется конфигурация (/etc/conf.d/net):

```

# LAN

config_eth0=( "192.168.1.1/24" )

# === IC ===

config_eth1=( "10.1.3.132/26" )

routes_eth1=(

    "10.0.0.0/8 via 10.1.3.129"

    "195.98.64.65 via 10.1.3.129"

    "195.98.64.66 via 10.1.3.129"

    "192.168.149.0/24 via 10.1.3.129"

)

config_ppp1=( "ppp" )

#link_ppp1="pty 'pptp 192.168.149.1 --nolaunchpppd'"

link_ppp1="pty 'pptp 192.168.149.129 --nolaunchpppd'"

username_ppp1='xxxxxx'

password_ppp1='xxxxxx'

pppd_ppp1=(

    "mru 1400"

    "mtu 1400"

    "updetach"

    "nodefaultroute"

    "lcp-echo-interval 15"

    "lcp-echo-failure 3"

)

routes_ppp1=(

    "83.139.128.0/18 via 195.98.64.222"

    "195.98.64.0/20 via 195.98.64.222"

    "217.25.224.0/20 via 195.98.64.222"

    "default via 195.98.64.222 table inet_ic"

    "default via 195.98.64.222 metric 1000"

)

# === CTC ===

config_eth2=( "172.31.255.254/30" )

config_ppp2=( "ppp" )

link_ppp2="eth2"

plugins_ppp2=( "pppoe" )

username_ppp2='xxxxxx'

password_ppp2='xxxxxx'

pppd_ppp2=(

    "noauth"

    "updetach"

    "nodefaultroute"

    "default-asyncmap"

    "ipcp-accept-remote"

    "ipcp-accept-local"

    "lcp-echo-interval 15"

    "lcp-echo-failure 3"

    "mru 1492"

    "mtu 1492"

    "persist"

    "holdoff 2"

    "lock"

)

routes_ppp2=(

    "80.82.32.0/19 via 80.82.53.100"

    "88.83.192.0/19 via 80.82.53.100"

    "77.45.128.0/17 via 80.82.53.100"

    "95.32.0.0/16 via 80.82.53.100"

    "default via 80.82.53.100 table inet_ctc"

    "default via 80.82.53.100 metric 2000"

)

```

С ней выявилась проблема: почему-то после поднятия интерфейса ppp2 его маршруты не добавляются. Проблема в принципе решается грязным хаком в файле /lib/rcscripts/net/pppd.sh вида: 

```

--- pppd.sh.bak 2007-10-24 02:59:26.000000000 +0400

+++ pppd.sh     2009-05-06 15:32:30.000000000 +0400

@@ -216,3 +216,4 @@

        # pppd will re-call us when we bring the interface up

-       exit 0

+#      exit 0

+    return 0

 }

```

Видно, что в исходном скрипте pppd_start (конец которой мы видим) не возвращает управление в вызывающую процедуру, а тупо прекращает скрипт (exit 0). А обещанного re-call почему-то не происходит. В результате: для ppp2 не добавляются маршруты из routes_ppp2, для ppp1 - почему-то добавляются (не понимаю, где именно это происходит), но если в /etc/conf.d/net добавить функцию postup, она всё равно не выполняется для ppp-интерфейсов. (Она выполняется скриптом /etc/init.d/net...., а поскольку в него возврат не происходит для ppp-интерфейсов, то...) Собственно, хак меняет поведение системы - мы возвращаемся в скрипт в /etc/init.d/net...., машруты добавляются и postup вызывается. Но при наличии хака в логах (только в логах, не на экране) при каждом нормальном старте ppp-интерфейса появляется сообщение, что он уже запущен (но всё отрабатывает корректно).

В связи с этим - вопрос: это я чего-то не понимаю, или это недоработка/баг скрипта, который работает с ppp? Как-то можно это исправить без хака?

Второй вопрос - более тонкий. В скриптах везде прописаны шлюзы провайдеров, через которые полагается ходить в их сети. Его адрес ppp узнаёт через ipcp (для этого стоит параметр ipcp-accept-remote). Так вот, для провайдера CTC он обычно тот, что указан (80.82.53.100), но иногда появляются и другие адреса (.124,.125) - у нашего провайдера стоит три взаимозаменяемых роутера, и в принципе обслуживать меня может любой из них. Адрес remote в этом случае получается другой, и все правила обламываются.

Есть ли возможность как-то указать "via ${REMOTE}", чтобы REMOTE подставилось именно в момент подключения - чтобы туда попадал именно тот фактический адрес шлюза, с которым я соединился в этот раз? 

Третий вопрос частично рассмотрен в net.example. Хочется автоматом добавлять правила для split-access (ip rule add from MY_IP lookup inet_...) при поднятии интерфейса. Для этого там предлагается объявить функции postup и postdown, объявить для каждого из интерфейсов по переменной rules_pppX, добавлять эти правила в postup, а убирать при остановке интерфейса в postdown. Но поскольку postup для ppp у меня не работает без грязного хака, то я пока не дошёл до исполнения такого решения. Однако, проблема возникнет и тут: один из провайдеров выдаёт мне каждый раз новый адрес MY_IP, который pppd узнаёт в момент соединения через ipcp, и этот фактический адрес и должен подставляться в правило вместо MY_IP.

Может ли кто-то мне посоветовать что-нибудь, что поможет мне в реализации задачи?

----------

