Statistics
| Branch: | Tag: | Revision:

root / common.sh @ a004c27e

History | View | Annotate | Download (8.5 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
  if [ -n "$EUI64" -a -n "$UPLINK" ]; then
30
    $SNF_NETWORK_LOG $0 "* ip -6 neigh del proxy $EUI64 dev $UPLINK"
31
    ip -6 neigh del proxy $EUI64 dev $UPLINK
32
  fi
33

    
34
}
35

    
36
function clear_routed_setup_firewall {
37

    
38
  for oldchain in protected unprotected limited; do
39
    iptables  -D FORWARD -o $INTERFACE -j $oldchain
40
    ip6tables -D FORWARD -o $INTERFACE -j $oldchain
41
  done
42

    
43
}
44

    
45
function clear_ebtables {
46

    
47
  runlocked $RUNLOCKED_OPTS ebtables -D FORWARD -i $INTERFACE -j $FROM
48
  runlocked $RUNLOCKED_OPTS ebtables -D FORWARD -o $INTERFACE -j $TO
49
  #runlocked $RUNLOCKED_OPTS ebtables -D OUTPUT -o $INTERFACE -j $TO
50

    
51
  runlocked $RUNLOCKED_OPTS ebtables -X $FROM
52
  runlocked $RUNLOCKED_OPTS ebtables -X $TO
53
}
54

    
55

    
56
function clear_nfdhcpd {
57

    
58
  rm $NFDHCPD_STATE_DIR/$INTERFACE
59

    
60
}
61

    
62

    
63
function routed_setup_ipv4 {
64

    
65
  if [ -z "$INTERFACE" -o -z "$NETWORK_GATEWAY" -o -z "$IP" -o -z "$TABLE" ]
66
  then
67
    return
68
  fi
69

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

    
73
	# route interface to the proper routing table
74
	ip rule add dev $INTERFACE table $TABLE
75

    
76
	# static route mapping IP -> INTERFACE
77
	ip route replace $IP proto static dev $INTERFACE table $TABLE
78

    
79
	# Enable proxy ARP
80
	echo 1 > /proc/sys/net/ipv4/conf/$INTERFACE/proxy_arp
81

    
82
}
83

    
84
function send_garp {
85

    
86
  # Send GARP from host to upstream router
87
  get_uplink $TABLE
88
  echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind
89
  # $SNF_NETWORK_LOG $0 "arping  -c3 -I $UPLINK -U $IP"
90
  # arping  -c3 -I $UPLINK -U $IP
91
  $SNF_NETWORK_LOG $0 "arpsend -U -c 1 -i $IP $UPLINK"
92
  arpsend -U -c 1 -i $IP $UPLINK
93
  echo 0 > /proc/sys/net/ipv4/ip_nonlocal_bind
94

    
95
}
96

    
97
function routed_setup_ipv6 {
98
	# Add a routing entry for the eui-64
99
  get_uplink $TABLE "-6"
100
  get_eui64 $MAC $NETWORK_SUBNET6
101

    
102
  if [ -z "$EUI64" -o -z "$TABLE" -o -z "$INTERFACE" -o -z "$UPLINK" ]
103
  then
104
    return
105
  fi
106

    
107
	ip -6 rule add dev $INTERFACE table $TABLE
108
	ip -6 ro replace $EUI64/128 dev $INTERFACE table $TABLE
109
	ip -6 neigh add proxy $EUI64 dev $UPLINK
110

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

    
115
  # Send Unsolicited Neighbor Advertisement
116
  $SNF_NETWORK_LOG $0 "ndsend $EUI64 $UPLINK"
117
  ndsend $EUI64 $UPLINK
118

    
119
}
120

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

    
144
	if [ "x$chain" != "x" ]; then
145
		iptables  -A FORWARD -o $INTERFACE -j $chain
146
		ip6tables -A FORWARD -o $INTERFACE -j $chain
147
	fi
148
}
149

    
150
function init_ebtables {
151

    
152
  runlocked $RUNLOCKED_OPTS ebtables -N $FROM
153
  runlocked $RUNLOCKED_OPTS ebtables -A FORWARD -i $INTERFACE -j $FROM
154
  runlocked $RUNLOCKED_OPTS ebtables -N $TO
155
  runlocked $RUNLOCKED_OPTS ebtables -A FORWARD -o $INTERFACE -j $TO
156

    
157
}
158

    
159

    
160
function setup_ebtables {
161

    
162
  # do not allow changes in ip-mac pair
163
  if [ -n "$IP"]; then
164
    runlocked $RUNLOCKED_OPTS ebtables -A $FROM --ip-source \! $IP -p ipv4 -j DROP
165
  fi
166
  runlocked $RUNLOCKED_OPTS ebtables -A $FROM -s \! $MAC -j DROP
167
  #accept dhcp responses from host (nfdhcpd)
168
  runlocked $RUNLOCKED_OPTS ebtables -A $TO -p ipv4 --ip-protocol=udp  --ip-destination-port=68 -j ACCEPT
169
  # allow only packets from the same mac prefix
170
  runlocked $RUNLOCKED_OPTS ebtables -A $TO -s \! $MAC/$MAC_MASK -j DROP
171
}
172

    
173
function setup_masq {
174

    
175
  # allow packets from/to router (for masquerading)
176
  # runlocked $RUNLOCKED_OPTS ebtables -A $TO -s $NODE_MAC -j ACCEPT
177
  # runlocked $RUNLOCKED_OPTS ebtables -A INPUT -i $INTERFACE -j $FROM
178
  # runlocked $RUNLOCKED_OPTS ebtables -A OUTPUT -o $INTERFACE -j $TO
179
  return
180

    
181
}
182

    
183
function setup_nfdhcpd {
184
	umask 022
185
  FILE=$NFDHCPD_STATE_DIR/$INTERFACE
186
  #IFACE is the interface from which the packet seems to arrive
187
  #needed in bridged mode where the packets seems to arrive from the
188
  #bridge and not from the tap
189
	cat >$FILE <<EOF
190
INDEV=$INDEV
191
IP=$IP
192
MAC=$MAC
193
HOSTNAME=$GANETI_INSTANCE_NAME
194
TAGS="$TAGS"
195
GATEWAY=$NETWORK_GATEWAY
196
SUBNET=$NETWORK_SUBNET
197
GATEWAY6=$NETWORK_GATEWAY6
198
SUBNET6=$NETWORK_SUBNET6
199
EUI64=$($MAC2EUI64 $MAC $NETWORK_SUBNET6 2>/dev/null)
200
EOF
201

    
202
}
203

    
204
function get_uplink {
205

    
206
  local table=$1
207
  local version=$2
208
  UPLINK=$(ip $version route list table "$table" | grep "default via" | awk '{print $5}')
209
  $SNF_NETWORK_LOG $0 "* uplink for table $table is $UPLINK"
210

    
211
}
212

    
213
# Because we do not have IPv6 value in our environment
214
# we caclulate it based on the NIC's MAC and the IPv6 subnet (if any)
215
# first argument MAC second IPv6 subnet
216
# Changes global value EUI64
217
get_eui64 () {
218

    
219
  local mac=$1
220
  local prefix=$2
221

    
222
  if [ -z "$prefix" ]; then
223
    EUI64=
224
  else
225
    EUI64=$($MAC2EUI64 $mac $prefix)
226
    $SNF_NETWORK_LOG $0 "* eui64 for $mac inside $prefix is $EUI64"
227
  fi
228

    
229
}
230

    
231

    
232
# DDNS related functions
233

    
234
# ommit zone statement
235
# nsupdate  will attempt determine the correct zone to update based on the rest of the input
236
send_command () {
237

    
238
  local command="$1"
239
  $SNF_NETWORK_LOG $0 "* $command"
240
  nsupdate -k $KEYFILE > /dev/null << EOF
241
  server $SERVER
242
  $command
243
  send
244
EOF
245

    
246
}
247

    
248

    
249
update_arecord () {
250

    
251
  local action=$1
252
  local command=
253
  if [ -n "$IP" ]; then
254
    command="update $action $GANETI_INSTANCE_NAME.$FZONE $TTL A $IP"
255
    send_command "$command"
256
  fi
257

    
258
}
259

    
260

    
261
update_aaaarecord () {
262

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

    
270
}
271

    
272

    
273
update_ptrrecord () {
274

    
275
  local action=$1
276
  local command=
277
  if [ -n "$IP" ]; then
278
    command="update $action $RLPART.$RZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
279
    send_command "$command"
280
  fi
281

    
282
}
283

    
284
update_ptr6record () {
285

    
286
  local action=$1
287
  local command=
288
  if [ -n "$EUI64" ]; then
289
    command="update $action $R6LPART$R6ZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
290
    send_command "$command"
291
  fi
292

    
293
}
294

    
295
update_all () {
296

    
297
  local action=$1
298
  update_arecord $action
299
  update_aaaarecord $action
300
  update_ptrrecord $action
301
  update_ptr6record $action
302

    
303
}
304

    
305

    
306
# first argument is an eui64 (IPv6)
307
# sets GLOBAL args R6REC, R6ZONE, R6LPART
308
# lets assume eui64=2001:648:2ffc:1::1
309
# the following commands produce:
310
# 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
311
# R6ZONE=1.0.0.0.c.f.f.2.8.4.6.0.1.0.0.2.ip6.arpa
312
# R6LPART=1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
313
get_rev6_info () {
314

    
315
  local eui64=$1
316
  if [ -z "$eui64" ]; then
317
    R6REC= ; R6ZONE= ; R6LPART= ;
318
  else
319
    R6REC=$(host $eui64 | egrep -o '([[:alnum:]]\.){32}ip6.arpa' )
320
    R6ZONE=$(echo $R6REC | awk -F. 'BEGIN{rpart="";} { for (i=32;i>16;i=i-1) rpart=$i "." rpart; } END{print rpart "ip6.arpa";}')
321
    R6LPART=$(echo $R6REC | awk -F. 'BEGIN{lpart="";} { for (i=16;i>0;i=i-1) lpart=$i "." lpart; } END{print lpart;}')
322
  fi
323

    
324
}
325

    
326

    
327
# first argument is an ipv4
328
# sets args RZONE, RLPART
329
# lets assume IP=203.0.113.1
330
# RZONE="113.0.203.in-add.arpa"
331
# RLPART="1"
332
get_rev4_info () {
333

    
334
  local ip=$1
335
  if [ -z "$ip" ]; then
336
    RZONE= ; RLPART= ;
337
  else
338
    OLDIFS=$IFS
339
    IFS=". "
340
    set -- $ip
341
    a=$1 ; b=$2; c=$3; d=$4;
342
    IFS=$OLDIFS
343
    RZONE="$c.$b.$a.in-addr.arpa"
344
    RLPART="$d"
345
  fi
346

    
347
}
348

    
349

    
350
# Query nameserver for entries related to the specific instance
351
# An example output is the following:
352
# www.google.com has address 173.194.113.114
353
# www.google.com has address 173.194.113.115
354
# www.google.com has address 173.194.113.116
355
# www.google.com has address 173.194.113.112
356
# www.google.com has address 173.194.113.113
357
# www.google.com has IPv6 address 2a00:1450:4001:80b::1012
358
query_dns () {
359

    
360
  HOSTQ="host -s -R 3 -W 3"
361
  HOST_IP_ALL=$($HOSTQ $GANETI_INSTANCE_NAME.$FZONE $SERVER | sed -n 's/.*has address //p')
362
  HOST_IP6_ALL=$($HOSTQ $GANETI_INSTANCE_NAME.$FZONE $SERVER | sed -n 's/.*has IPv6 address //p')
363

    
364
}