Statistics
| Branch: | Tag: | Revision:

root / common.sh @ 6afbe696

History | View | Annotate | Download (8.9 kB)

1
#!/bin/bash
2

    
3
source /etc/default/snf-network
4

    
5
function try {
6

    
7
  $1 &>/dev/null || true
8

    
9
}
10

    
11
function clear_routed_setup_ipv4 {
12

    
13
 arptables -D OUTPUT -o $INTERFACE --opcode request -j mangle
14
 while ip rule del dev $INTERFACE; do :; done
15
 iptables -D FORWARD -i $INTERFACE -p udp --dport 67 -j DROP
16

    
17
}
18

    
19
function clear_routed_setup_ipv6 {
20

    
21
 while ip -6 rule del dev $INTERFACE; do :; done
22

    
23
}
24

    
25
function delete_neighbor_proxy {
26

    
27
  get_uplink $LINK "-6"
28
  get_eui64 $MAC $NETWORK_SUBNET6
29

    
30
  if [ -z "$EUI64" -z -o "$UPLINK" ]; then
31
    return
32
  fi
33

    
34
  $SNF_NETWORK_LOG $0 "ip -6 neigh del proxy $EUI64 dev $UPLINK"
35
  ip -6 neigh del proxy $EUI64 dev $UPLINK
36

    
37
}
38

    
39
function clear_routed_setup_firewall {
40

    
41
  for oldchain in protected unprotected limited; do
42
    iptables  -D FORWARD -o $INTERFACE -j $oldchain
43
    ip6tables -D FORWARD -o $INTERFACE -j $oldchain
44
  done
45

    
46
}
47

    
48
function clear_ebtables {
49

    
50
  runlocked $RUNLOCKED_OPTS ebtables -D FORWARD -i $INTERFACE -j $FROM
51
  runlocked $RUNLOCKED_OPTS ebtables -D INPUT -i $INTERFACE -j $FROM
52
  runlocked $RUNLOCKED_OPTS ebtables -D FORWARD -o $INTERFACE -j $TO
53
  runlocked $RUNLOCKED_OPTS ebtables -D OUTPUT -o $INTERFACE -j $TO
54

    
55
  runlocked $RUNLOCKED_OPTS ebtables -X $FROM
56
  runlocked $RUNLOCKED_OPTS ebtables -X $TO
57
}
58

    
59

    
60
function clear_nfdhcpd {
61

    
62
  rm $NFDHCPD_STATE_DIR/$INTERFACE
63

    
64
}
65

    
66

    
67
function routed_setup_ipv4 {
68

    
69
  if [ -z "$INTERFACE" -o -z "$NETWORK_GATEWAY" -o -z "$IP" -o -z "$TABLE" ]
70
  then
71
    return
72
  fi
73

    
74
	# mangle ARPs to come from the gw's IP
75
	arptables -A OUTPUT -o $INTERFACE --opcode request -j mangle --mangle-ip-s    "$NETWORK_GATEWAY"
76

    
77
	# route interface to the proper routing table
78
	ip rule add dev $INTERFACE table $TABLE
79

    
80
	# static route mapping IP -> INTERFACE
81
	ip route replace $IP proto static dev $INTERFACE table $TABLE
82

    
83
	# Enable proxy ARP
84
	echo 1 > /proc/sys/net/ipv4/conf/$INTERFACE/proxy_arp
85

    
86
}
87

    
88
function send_garp {
89

    
90
  get_uplink $TABLE
91
  if [ -z "$IP" -o -z "$UPLINK" ]; then
92
    return
93
  fi
94

    
95
  # Send GARP from host to upstream router
96
  echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind
97
  $SNF_NETWORK_LOG $0 "arpsend -U -i $IP -c1 $UPLINK"
98
  arpsend -U -i $IP -c1 $UPLINK
99
  echo 0 > /proc/sys/net/ipv4/ip_nonlocal_bind
100

    
101
}
102

    
103
function routed_setup_ipv6 {
104
	# Add a routing entry for the eui-64
105
  get_uplink $TABLE "-6"
106
  get_eui64 $MAC $NETWORK_SUBNET6
107

    
108
  if [ -z "$EUI64" -o -z "$TABLE" -o -z "$INTERFACE" -o -z "$UPLINK" ]
109
  then
110
    return
111
  fi
112

    
113
	ip -6 rule add dev $INTERFACE table $TABLE
114
	ip -6 ro replace $EUI64/128 dev $INTERFACE table $TABLE
115
	ip -6 neigh add proxy $EUI64 dev $UPLINK
116

    
117
	# disable proxy NDP since we're handling this on userspace
118
	# this should be the default, but better safe than sorry
119
	echo 0 > /proc/sys/net/ipv6/conf/$INTERFACE/proxy_ndp
120

    
121
  # Send Unsolicited Neighbor Advertisement
122
  $SNF_NETWORK_LOG $0 "ndsend $EUI64 $UPLINK"
123
  ndsend $EUI64 $UPLINK
124

    
125
}
126

    
127
# pick a firewall profile per NIC, based on tags (and apply it)
128
function routed_setup_firewall {
129
	# for latest ganeti there is no need to check other but uuid
130
	ifprefixindex="synnefo:network:$INTERFACE_INDEX:"
131
	ifprefixname="synnefo:network:$INTERFACE_NAME:"
132
	ifprefixuuid="synnefo:network:$INTERFACE_UUID:"
133
	for tag in $TAGS; do
134
		tag=${tag#$ifprefixindex}
135
		tag=${tag#$ifprefixname}
136
		tag=${tag#$ifprefixuuid}
137
		case $tag in
138
		protected)
139
			chain=protected
140
		;;
141
		unprotected)
142
			chain=unprotected
143
		;;
144
		limited)
145
			chain=limited
146
		;;
147
		esac
148
	done
149

    
150
	if [ "x$chain" != "x" ]; then
151
		iptables  -A FORWARD -o $INTERFACE -j $chain
152
		ip6tables -A FORWARD -o $INTERFACE -j $chain
153
	fi
154
}
155

    
156
function init_ebtables {
157

    
158
  runlocked $RUNLOCKED_OPTS ebtables -N $FROM -P RETURN
159
  runlocked $RUNLOCKED_OPTS ebtables -A FORWARD -i $INTERFACE -j $FROM
160
  # This is needed for multicast packets
161
  runlocked $RUNLOCKED_OPTS ebtables -A INPUT -i $INTERFACE -j $FROM
162

    
163
  runlocked $RUNLOCKED_OPTS ebtables -N $TO -P RETURN
164
  runlocked $RUNLOCKED_OPTS ebtables -A FORWARD -o $INTERFACE -j $TO
165
  # This is needed for multicast packets
166
  runlocked $RUNLOCKED_OPTS ebtables -A OUTPUT -o $INTERFACE -j $TO
167

    
168
}
169

    
170

    
171
function setup_ebtables {
172

    
173
  # do not allow changes in ip-mac pair
174
  if [ -n "$IP" ]; then
175
    :; # runlocked $RUNLOCKED_OPTS ebtables -A $FROM --ip-source \! $IP -p ipv4 -j DROP
176
  fi
177
  runlocked $RUNLOCKED_OPTS ebtables -A $FROM -s \! $MAC -j DROP
178
  # accept dhcp responses from host (nfdhcpd)
179
  # this is actually not needed because nfdhcpd opens a socket and binds is with
180
  # tap interface so dhcp response does not go through bridge
181
  # runlocked $RUNLOCKED_OPTS ebtables -A $TO -s $INDEV_MAC -p ipv4 --ip-protocol=udp  --ip-destination-port=68 -j ACCEPT
182
  # allow only packets from the same mac prefix
183
  runlocked $RUNLOCKED_OPTS ebtables -A $TO -s \! $MAC/$MAC_MASK -j DROP
184
}
185

    
186
function setup_masq {
187

    
188
  # allow packets from/to router (for masquerading)
189
  # runlocked $RUNLOCKED_OPTS ebtables -A $TO -s $NODE_MAC -j ACCEPT
190
  # runlocked $RUNLOCKED_OPTS ebtables -A INPUT -i $INTERFACE -j $FROM
191
  # runlocked $RUNLOCKED_OPTS ebtables -A OUTPUT -o $INTERFACE -j $TO
192
  return
193

    
194
}
195

    
196
function setup_nfdhcpd {
197
	umask 022
198
  FILE=$NFDHCPD_STATE_DIR/$INTERFACE
199
  #IFACE is the interface from which the packet seems to arrive
200
  #needed in bridged mode where the packets seems to arrive from the
201
  #bridge and not from the tap
202
	cat >$FILE <<EOF
203
INDEV=$INDEV
204
IP=$IP
205
MAC=$MAC
206
HOSTNAME=$INSTANCE
207
TAGS="$TAGS"
208
GATEWAY=$NETWORK_GATEWAY
209
SUBNET=$NETWORK_SUBNET
210
GATEWAY6=$NETWORK_GATEWAY6
211
SUBNET6=$NETWORK_SUBNET6
212
EUI64=$($MAC2EUI64 $MAC $NETWORK_SUBNET6 2>/dev/null)
213
EOF
214

    
215
}
216

    
217
function get_uplink {
218

    
219
  local table=$1
220
  local version=$2
221
  UPLINK=$(ip $version route list table $table | grep "default via" | awk '{print $5}')
222
  $SNF_NETWORK_LOG $0 "* uplink for table $table is $UPLINK"
223

    
224
}
225

    
226
# Because we do not have IPv6 value in our environment
227
# we caclulate it based on the NIC's MAC and the IPv6 subnet (if any)
228
# first argument MAC second IPv6 subnet
229
# Changes global value EUI64
230
get_eui64 () {
231

    
232
  local mac=$1
233
  local prefix=$2
234

    
235
  if [ -z "$prefix" ]; then
236
    EUI64=
237
  else
238
    EUI64=$($MAC2EUI64 $mac $prefix)
239
    $SNF_NETWORK_LOG $0 "* eui64 for $mac inside $prefix is $EUI64"
240
  fi
241

    
242
}
243

    
244

    
245
# DDNS related functions
246

    
247
# ommit zone statement
248
# nsupdate  will attempt determine the correct zone to update based on the rest of the input
249
send_command () {
250

    
251
  local command="$1"
252
  $SNF_NETWORK_LOG $0 "* $command"
253
  nsupdate -k $KEYFILE > /dev/null << EOF
254
  server $SERVER
255
  $command
256
  send
257
EOF
258

    
259
}
260

    
261

    
262
update_arecord () {
263

    
264
  local action=$1
265
  local command=
266
  if [ -n "$IP" ]; then
267
    command="update $action $GANETI_INSTANCE_NAME.$FZONE $TTL A $IP"
268
    send_command "$command"
269
  fi
270

    
271
}
272

    
273

    
274
update_aaaarecord () {
275

    
276
  local action=$1
277
  local command=
278
  if [ -n "$EUI64" ]; then
279
    command="update $action $GANETI_INSTANCE_NAME.$FZONE $TTL AAAA $EUI64"
280
    send_command "$command"
281
  fi
282

    
283
}
284

    
285

    
286
update_ptrrecord () {
287

    
288
  local action=$1
289
  local command=
290
  if [ -n "$IP" ]; then
291
    command="update $action $RLPART.$RZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
292
    send_command "$command"
293
  fi
294

    
295
}
296

    
297
update_ptr6record () {
298

    
299
  local action=$1
300
  local command=
301
  if [ -n "$EUI64" ]; then
302
    command="update $action $R6LPART$R6ZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
303
    send_command "$command"
304
  fi
305

    
306
}
307

    
308
update_all () {
309

    
310
  local action=$1
311
  update_arecord $action
312
  update_aaaarecord $action
313
  update_ptrrecord $action
314
  update_ptr6record $action
315

    
316
}
317

    
318

    
319
# first argument is an eui64 (IPv6)
320
# sets GLOBAL args R6REC, R6ZONE, R6LPART
321
# lets assume eui64=2001:648:2ffc:1::1
322
# the following commands produce:
323
# R6REC=1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.c.f.f.2.8.4.6.0.1.0.0.2.ip6.arpa
324
# R6ZONE=1.0.0.0.c.f.f.2.8.4.6.0.1.0.0.2.ip6.arpa
325
# R6LPART=1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
326
get_rev6_info () {
327

    
328
  local eui64=$1
329
  if [ -z "$eui64" ]; then
330
    R6REC= ; R6ZONE= ; R6LPART= ;
331
  else
332
    R6REC=$(host $eui64 | egrep -o '([[:alnum:]]\.){32}ip6.arpa' )
333
    R6ZONE=$(echo $R6REC | awk -F. 'BEGIN{rpart="";} { for (i=32;i>16;i=i-1) rpart=$i "." rpart; } END{print rpart "ip6.arpa";}')
334
    R6LPART=$(echo $R6REC | awk -F. 'BEGIN{lpart="";} { for (i=16;i>0;i=i-1) lpart=$i "." lpart; } END{print lpart;}')
335
  fi
336

    
337
}
338

    
339

    
340
# first argument is an ipv4
341
# sets args RZONE, RLPART
342
# lets assume IP=203.0.113.1
343
# RZONE="113.0.203.in-add.arpa"
344
# RLPART="1"
345
get_rev4_info () {
346

    
347
  local ip=$1
348
  if [ -z "$ip" ]; then
349
    RZONE= ; RLPART= ;
350
  else
351
    OLDIFS=$IFS
352
    IFS=". "
353
    set -- $ip
354
    a=$1 ; b=$2; c=$3; d=$4;
355
    IFS=$OLDIFS
356
    RZONE="$c.$b.$a.in-addr.arpa"
357
    RLPART="$d"
358
  fi
359

    
360
}
361

    
362

    
363
# Query nameserver for entries related to the specific instance
364
# An example output is the following:
365
# www.google.com has address 173.194.113.114
366
# www.google.com has address 173.194.113.115
367
# www.google.com has address 173.194.113.116
368
# www.google.com has address 173.194.113.112
369
# www.google.com has address 173.194.113.113
370
# www.google.com has IPv6 address 2a00:1450:4001:80b::1012
371
query_dns () {
372

    
373
  HOSTQ="host -s -R 3 -W 3"
374
  HOST_IP_ALL=$($HOSTQ $GANETI_INSTANCE_NAME.$FZONE $SERVER | sed -n 's/.*has address //p')
375
  HOST_IP6_ALL=$($HOSTQ $GANETI_INSTANCE_NAME.$FZONE $SERVER | sed -n 's/.*has IPv6 address //p')
376

    
377
}