Gentoo Archives: gentoo-commits

From: "Robin H. Johnson" <robbat2@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/netifrc:master commit in: doc/, net/
Date: Tue, 05 Jul 2016 18:15:01
Message-Id: 1462101076.97da3ab2158db402fd20b440cefe7a7be7501d6d.robbat2@OpenRC
1 commit: 97da3ab2158db402fd20b440cefe7a7be7501d6d
2 Author: Emeric Verschuur <emeric <AT> mbedsys <DOT> org>
3 AuthorDate: Sun May 1 11:11:16 2016 +0000
4 Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
5 CommitDate: Sun May 1 11:11:16 2016 +0000
6 URL: https://gitweb.gentoo.org/proj/netifrc.git/commit/?id=97da3ab2
7
8 Adding L2TP (v3) module (net/l2tp.sh) to support L2TPv3 link
9
10 doc/net.example.Linux.in | 24 +++++++
11 net/l2tp.sh | 169 +++++++++++++++++++++++++++++++++++++++++++++++
12 2 files changed, 193 insertions(+)
13
14 diff --git a/doc/net.example.Linux.in b/doc/net.example.Linux.in
15 index f65c03d..72608bb 100644
16 --- a/doc/net.example.Linux.in
17 +++ b/doc/net.example.Linux.in
18 @@ -985,6 +985,30 @@
19 #relay_6to4="192.168.3.2"
20 #suffix_6to4=":ff"
21
22 +# For L2TP (v3) link
23 +# WARNING: sys-apps/iproute2 is required to use this module
24 +# You may have to add "l2tp" to modules list
25 +#
26 +# A L2 link between need a session within a tunnel
27 +# 1 session <=> 1 interface and 1 tunnel <=> n session(s)
28 +# a tunnel can host several session (shared by several interfaces)
29 +#
30 +# Example to create 3 L2TPv3 links where (see man ip, iproute2 manual for more details):
31 +# * l2tpeth0 and l2tpeth1 are tho sessions into a same (shared) tunnel (encap IP)
32 +# * l2tpeth2 is a session into an separate tunnel (encap UDP)
33 +#
34 +#l2tptunnel_l2tpeth0="remote 1.2.3.4 local 1.2.4.3 encap ip tunnel_id 1 peer_tunnel_id 1"
35 +#l2tpsession_l2tpeth0="tunnel_id 1 session_id 1 peer_session_id 1"
36 +#config_l2tpeth="10.100.0.1/24"
37 +#
38 +#l2tptunnel_l2tpeth1="remote 1.2.3.4 local 1.2.4.3 encap ip tunnel_id 1 peer_tunnel_id 1"
39 +#l2tpsession_l2tpeth1="tunnel_id 1 session_id 2 peer_session_id 2"
40 +#config_l2tpeth1="10.100.1.1/24"
41 +#
42 +#l2tptunnel_l2tpeth2="remote 1.2.3.4 local 1.2.4.3 encap udp tunnel_id 2 peer_tunnel_id 2 udp_sport 5000 udp_dport 6000"
43 +#l2tpsession_l2tpeth2="tunnel_id 2 session_id 1 peer_session_id 1"
44 +#config_l2tpeth2="10.100.2.1/24"
45 +
46 #-----------------------------------------------------------------------------
47 # Advanced Routing
48 # WARNING: For advanced routing you MUST be using sys-apps/iproute2
49
50 diff --git a/net/l2tp.sh b/net/l2tp.sh
51 new file mode 100644
52 index 0000000..24f5f8c
53 --- /dev/null
54 +++ b/net/l2tp.sh
55 @@ -0,0 +1,169 @@
56 +# Copyright (c) 2016 Emeric Verschuur <emeric@×××××××.org>
57 +# All rights reserved. Released under the 2-clause BSD license.
58 +
59 +l2tp_depend()
60 +{
61 + program ip
62 + before bridge interface macchanger
63 +}
64 +
65 +# Extract parameter list to shell vars
66 +# 1. variable prefix
67 +# 2. string to parse
68 +_l2tp_eval_props() {
69 + local prop_pref=$1
70 + local prop_list=$2
71 + eval set -- "$3"
72 + while [ -n "$1" ]; do
73 + eval "case $1 in
74 + $prop_list)
75 + $prop_pref$1=\"$2\"
76 + shift
77 + shift
78 + ;;
79 + *)
80 + l2tp_err=\"invalid property $1\"
81 + return 1
82 + ;;
83 +
84 + esac" || return 1
85 + done
86 + return 0
87 +}
88 +
89 +_is_l2tp() {
90 + eval "$(ip l2tp show session | \
91 + awk "match(\$0, /^Session ([0-9]+) in tunnel ([0-9]+)\$/, ret) {sid=ret[1]; tid=ret[2]}
92 + match(\$0, /^[ ]*interface name: ${IFACE}\$/) {print \"session_id=\"sid\";tunnel_id=\"tid; exit}")"
93 + test -n "$session_id"
94 +}
95 +
96 +# Get tunnel info
97 +# 1. Output variable prefix
98 +# 2. Tunnel ID to find
99 +_l2tp_get_tunnel_info() {
100 + local found
101 + eval "$(ip l2tp show tunnel | \
102 + awk -v id=$2 -v prefix=$1 '
103 + match($0, /^Tunnel ([0-9]+), encap (IP|UDP)$/, ret) {
104 + if (found == "1") exit;
105 + if (ret[1] == id) {
106 + print "found=1;"
107 + print prefix "tunnel_id=" ret[1] ";"
108 + print prefix "encap=" ret[2] ";";
109 + found="1"
110 + }
111 + }
112 + match($0, /^[ ]*From ([^ ]+) to ([^ ]+)$/, ret) {
113 + if (found == "1") {
114 + print prefix "local=" ret[1] ";";
115 + print prefix "remote=" ret[2] ";";
116 + }
117 + }
118 + match($0, /^[ ]*Peer tunnel ([0-9]+)$/, ret) {
119 + if (found == "1") {
120 + print prefix "peer_tunnel_id=" ret[1] ";";
121 + }
122 + }
123 + match($0, /^[ ]*UDP source \/ dest ports: ([0-9]+)\/([0-9]+)$/, ret) {
124 + if (found == "1") {
125 + print prefix "udp_sport=" ret[1] ";";
126 + print prefix "udp_dport=" ret[2] ";";
127 + }
128 + }')"
129 + test -n "$found"
130 +}
131 +
132 +_ip_l2tp_add() {
133 + local e
134 + e="$(LC_ALL=C ip l2tp add $@ 2>&1 1>/dev/null)"
135 + case $e in
136 + "")
137 + return 0
138 + ;;
139 + "RTNETLINK answers: No such process")
140 + # seems to not be a fatal error but I don't know why I have this error... hmmm
141 + ewarn "ip l2tp add $2 error: $e"
142 + return 0
143 + ;;
144 + *)
145 + eend 1 "ip l2tp add $2 error: $e"
146 + return 1
147 + ;;
148 + esac
149 +
150 +}
151 +
152 +l2tp_pre_start()
153 +{
154 + local l2tpsession=
155 + eval l2tpsession=\$l2tpsession_${IFVAR}
156 + test -n "${l2tpsession}" || return 0
157 +
158 + ebegin "Creating L2TP tunnel ${IFVAR}"
159 + local l2tp_err s_name s_tunnel_id s_session_id s_peer_session_id s_cookie s_peer_cookie s_offset s_peer_offset s_l2spec_type
160 + if ! _l2tp_eval_props s_ "name|tunnel_id|session_id|peer_session_id|cookie|peer_cookie|offset|peer_offset|l2spec_type" "${l2tpsession}"; then
161 + eend 1 "l2tpsession_${IFVAR} syntax error: $l2tp_err"
162 + return 1
163 + fi
164 + if [ -n "$s_name" ]; then
165 + eend 1 "l2tpsession_${IFVAR} error: please remove the \"name\" parameter (this parameter is managed by the system)"
166 + return 1
167 + fi
168 + # Try to load mendatory l2tp_eth kernel module
169 + if ! modprobe l2tp_eth; then
170 + eend 1 "l2tp_eth module not present in your kernel (please enable CONFIG_L2TP_ETH option in your kernel config)"
171 + return 1
172 + fi
173 + local l2tptunnel=
174 + eval l2tptunnel=\$l2tptunnel_${IFVAR}
175 + if [ -n "${l2tptunnel}" ]; then
176 + local t_tunnel_id t_encap t_local t_remote t_peer_tunnel_id t_udp_sport t_udp_dport
177 + _l2tp_eval_props t_ "remote|local|encap|tunnel_id|peer_tunnel_id|encap|udp_sport|udp_dport" "${l2tptunnel}"
178 + # if encap=ip we need l2tp_ip kernel module
179 + if [ "${t_encap^^}" = "IP" ] && ! modprobe l2tp_ip; then
180 + eend 1 "l2tp_ip module not present in your kernel (please enable CONFIG_L2TP_IP option in your kernel config)"
181 + return 1
182 + fi
183 + # Search for an existing tunnel with the same ID
184 + local f_tunnel_id f_encap f_local f_remote f_peer_tunnel_id f_udp_sport f_udp_dport
185 + if _l2tp_get_tunnel_info f_ $t_tunnel_id; then
186 + # check if the existing tunnel has the same property than expected
187 + if [ "tunnel_id:$f_tunnel_id;encap:$f_encap;local:$f_local;remote:$f_remote;
188 + peer_tunnel_id:$f_peer_tunnel_id;udp_sport:$f_udp_sport;udp_dport:$f_udp_dport" \
189 + != "tunnel_id:$t_tunnel_id;encap:${t_encap^^};local:$t_local;remote:$t_remote;
190 + peer_tunnel_id:$t_peer_tunnel_id;udp_sport:$t_udp_sport;udp_dport:$t_udp_dport" ]; then
191 + eend 1 "There are an existing tunnel with id=$s_tunnel_id, but the properties mismatch with the one you want to create"
192 + return 1
193 + fi
194 + else
195 + veinfo ip l2tp add tunnel ${l2tptunnel}
196 + _ip_l2tp_add tunnel ${l2tptunnel} || return 1
197 + fi
198 + elif ! ip l2tp show tunnel | grep -Eq "^Tunnel $s_tunnel_id,"; then
199 + # no l2tptunnel_<INTF> declaration, assume that the tunnel is already present
200 + # checking if tunnel_id exists otherwise raise an error
201 + eend 1 "Tunnel id=$s_tunnel_id no found (you may have to set l2tptunnel_${IFVAR})"
202 + return 1
203 + fi
204 + veinfo ip l2tp add session ${l2tpsession} name "${IFACE}"
205 + _ip_l2tp_add session ${l2tpsession} name "${IFACE}" || return 1
206 + _up
207 +}
208 +
209 +
210 +l2tp_post_stop()
211 +{
212 + local session_id tunnel_id
213 + _is_l2tp || return 0
214 +
215 + ebegin "Destroying L2TP tunnel ${IFACE}"
216 + veinfo ip l2tp del session tunnel_id $tunnel_id session_id $session_id
217 + ip l2tp del session tunnel_id $tunnel_id session_id $session_id
218 + if ! ip l2tp show session | grep -Eq "^Session [0-9]+ in tunnel $tunnel_id\$"; then
219 + #tunnel $tunnel_id no longer used, destoying it...
220 + veinfo ip l2tp del tunnel tunnel_id $tunnel_id
221 + ip l2tp del tunnel tunnel_id $tunnel_id
222 + fi
223 + eend $?
224 +}