Nav apraksta

l2tp.sh 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. # l2tp.sh - L2TPv3 tunnel backend
  2. # Copyright (c) 2010 OpenWrt.org
  3. l2tp_next_tunnel_id() {
  4. local max=0
  5. local val
  6. for val in $(
  7. local l
  8. l2tpv3tun show tunnel | while read l; do
  9. case "$l" in
  10. Tunnel*,*encap*) l="${l#Tunnel }"; echo "${l%%,*}";;
  11. esac
  12. done
  13. ); do
  14. [ "$val" -gt "$max" ] && max="$val"
  15. done
  16. echo $((max + 1))
  17. }
  18. l2tp_next_session_id() {
  19. local tunnel="$1"
  20. local max=0
  21. local val
  22. for val in $(
  23. local l
  24. l2tpv3tun show session${tunnel:+ tunnel_id "$tunnel"} | while read l; do
  25. case "$l" in
  26. Session*in*) l="${l#Session }"; echo "${l%% *}";;
  27. esac
  28. done
  29. ); do
  30. [ "$val" -gt "$max" ] && max="$val"
  31. done
  32. echo $((max + 1))
  33. }
  34. l2tp_tunnel_exists() {
  35. test -n "$(l2tpv3tun show tunnel tunnel_id "$1" 2>/dev/null)"
  36. }
  37. l2tp_session_exists() {
  38. test -n "$(l2tpv3tun show session tunnel_id "$1" session_id "$2" 2>/dev/null)"
  39. }
  40. l2tp_ifname() {
  41. l2tpv3tun show session tunnel_id "$1" session_id "$2" 2>/dev/null | \
  42. sed -ne 's/^.*interface name: //p'
  43. }
  44. l2tp_lock() {
  45. lock /var/lock/l2tp-setup
  46. }
  47. l2tp_unlock() {
  48. lock -u /var/lock/l2tp-setup
  49. }
  50. l2tp_log() {
  51. logger -t "ifup-l2tp" "$@"
  52. }
  53. # Hook into scan_interfaces() to synthesize a .device option
  54. # This is needed for /sbin/ifup to properly dispatch control
  55. # to setup_interface_l2tp() even if no .ifname is set in
  56. # the configuration.
  57. scan_l2tp() {
  58. local dev
  59. config_get dev "$1" device
  60. config_set "$1" device "${dev:+$dev }l2tp-$1"
  61. }
  62. coldplug_interface_l2tp() {
  63. setup_interface_l2tp "l2tp-$1" "$1"
  64. }
  65. setup_interface_l2tp() {
  66. local iface="$1"
  67. local cfg="$2"
  68. local link="l2tp-$cfg"
  69. l2tp_lock
  70. # prevent recursion
  71. local up="$(uci_get_state network "$cfg" up 0)"
  72. [ "$up" = 0 ] || {
  73. l2tp_unlock
  74. return 0
  75. }
  76. local tunnel_id
  77. config_get tunnel_id "$cfg" tunnel_id
  78. [ -n "$tunnel_id" ] || {
  79. tunnel_id="$(l2tp_next_tunnel_id)"
  80. uci_set_state network "$cfg" tunnel_id "$tunnel_id"
  81. l2tp_log "No tunnel ID specified, assuming $tunnel_id"
  82. }
  83. local peer_tunnel_id
  84. config_get peer_tunnel_id "$cfg" peer_tunnel_id
  85. [ -n "$peer_tunnel_id" ] || {
  86. peer_tunnel_id="$tunnel_id"
  87. uci_set_state network "$cfg" peer_tunnel_id "$peer_tunnel_id"
  88. l2tp_log "No peer tunnel ID specified, assuming $peer_tunnel_id"
  89. }
  90. local encap
  91. config_get encap "$cfg" encap udp
  92. local sport dport
  93. [ "$encap" = udp ] && {
  94. config_get sport "$cfg" sport 1701
  95. config_get dport "$cfg" dport 1701
  96. }
  97. local peeraddr
  98. config_get peeraddr "$cfg" peeraddr
  99. [ -z "$peeraddr" ] && config_get peeraddr "$cfg" peer6addr
  100. local localaddr
  101. case "$peeraddr" in
  102. *:*) config_get localaddr "$cfg" local6addr ;;
  103. *) config_get localaddr "$cfg" localaddr ;;
  104. esac
  105. [ -n "$localaddr" -a -n "$peeraddr" ] || {
  106. l2tp_log "Missing local or peer address for tunnel $cfg - skipping"
  107. return 1
  108. }
  109. (
  110. while ! l2tp_tunnel_exists "$tunnel_id"; do
  111. [ -n "$sport" ] && l2tpv3tun show tunnel 2>/dev/null | grep -q "ports: $sport/" && {
  112. l2tp_log "There already is a tunnel with src port $sport - skipping"
  113. l2tp_unlock
  114. return 1
  115. }
  116. l2tpv3tun add tunnel tunnel_id "$tunnel_id" peer_tunnel_id "$peer_tunnel_id" \
  117. encap "$encap" local "$localaddr" remote "$peeraddr" \
  118. ${sport:+udp_sport "$sport"} ${dport:+udp_dport "$dport"}
  119. # Wait for tunnel
  120. sleep 1
  121. done
  122. local session_id
  123. config_get session_id "$cfg" session_id
  124. [ -n "$session_id" ] || {
  125. session_id="$(l2tp_next_session_id "$tunnel_id")"
  126. uci_set_state network "$cfg" session_id "$session_id"
  127. l2tp_log "No session ID specified, assuming $session_id"
  128. }
  129. local peer_session_id
  130. config_get peer_session_id "$cfg" peer_session_id
  131. [ -n "$peer_session_id" ] || {
  132. peer_session_id="$session_id"
  133. uci_set_state network "$cfg" peer_session_id "$peer_session_id"
  134. l2tp_log "No peer session ID specified, assuming $peer_session_id"
  135. }
  136. while ! l2tp_session_exists "$tunnel_id" "$session_id"; do
  137. l2tpv3tun add session ifname "$link" tunnel_id "$tunnel_id" \
  138. session_id "$session_id" peer_session_id "$peer_session_id"
  139. # Wait for session
  140. sleep 1
  141. done
  142. local dev
  143. config_get dev "$cfg" device
  144. local ifn
  145. config_get ifn "$cfg" ifname
  146. uci_set_state network "$cfg" ifname "${ifn:-$dev}"
  147. uci_set_state network "$cfg" device "$dev"
  148. local mtu
  149. config_get mtu "$cfg" mtu 1462
  150. local ttl
  151. config_get ttl "$cfg" ttl
  152. ip link set mtu "$mtu" ${ttl:+ ttl "$ttl"} dev "$link"
  153. # IP setup inherited from proto static
  154. prepare_interface "$link" "$cfg"
  155. setup_interface_static "${ifn:-$dev}" "$cfg"
  156. ip link set up dev "$link"
  157. uci_set_state network "$cfg" up 1
  158. l2tp_unlock
  159. ) &
  160. }
  161. stop_interface_l2tp() {
  162. local cfg="$1"
  163. local link="l2tp-$cfg"
  164. local tunnel=$(uci_get_state network "$cfg" tunnel_id)
  165. local session=$(uci_get_state network "$cfg" session_id)
  166. [ -n "$tunnel" ] && [ -n "$session" ] && {
  167. l2tpv3tun del session tunnel_id "$tunnel" session_id "$session"
  168. l2tpv3tun del tunnel tunnel_id "$tunnel"
  169. }
  170. }