Clear existing binding before adding new
[snf-network] / kvm-vif-bridge
1 #!/bin/bash
2
3 # This is an example of a Ganeti kvm ifup script that configures network
4 # interfaces based on the initial deployment of the Okeanos project
5
6 TAP_CONSTANT_MAC=cc:47:52:4e:45:54 # GRNET in hex :-)
7 MAC2EUI64=/usr/bin/mac2eui64
8 NFDHCPD_STATE_DIR=/var/lib/nfdhcpd
9
10 function clear_routed_setup_ipv4 {
11
12  arptables -D OUTPUT -o $INTERFACE --opcode request -j mangle
13  while ip rule del dev $INTERFACE; do :; done
14  iptables -D FORWARD -i $INTERFACE -p udp --dport 67 -j DROP
15
16 }
17
18 function clear_routed_setup_ipv6 {
19
20  while ip -6 rule del dev $INTERFACE; do :; done
21
22 }
23
24
25 function clear_routed_setup_firewall {
26
27   for oldchain in protected unprotected limited; do
28     iptables  -D FORWARD -o $INTERFACE -j $oldchain
29     ip6tables -D FORWARD -o $INTERFACE -j $oldchain
30   done
31
32 }
33
34 function clear_ebtables {
35
36   ebtables -D FORWARD -i $TAP -j $FROM
37   ebtables -D FORWARD -o $TAP -j $TO
38   #ebtables -D OUTPUT -o $TAP -j $TO
39
40   ebtables -X $FROM
41   ebtables -X $TO
42 }
43
44
45 function clear_nfdhcpd {
46
47   rm $NFDHCPD_STATE_DIR/$INTERFACE
48
49 }
50
51
52 function routed_setup_ipv4 {
53
54         # mangle ARPs to come from the gw's IP
55         arptables -A OUTPUT -o $INTERFACE --opcode request -j mangle --mangle-ip-s    "$NETWORK_GATEWAY"
56
57         # route interface to the proper routing table
58         ip rule add dev $INTERFACE table $TABLE
59
60         # static route mapping IP -> INTERFACE
61         ip route replace $IP proto static dev $INTERFACE table $TABLE
62
63         # Enable proxy ARP
64         echo 1 > /proc/sys/net/ipv4/conf/$INTERFACE/proxy_arp
65 }
66
67 function routed_setup_ipv6 {
68         # Add a routing entry for the eui-64
69         prefix=$NETWORK_SUBNET6
70         uplink=$(ip -6 route list table $TABLE | grep "default via" | awk '{print $5}')
71         eui64=$($MAC2EUI64 $MAC $prefix)
72
73
74         ip -6 rule add dev $INTERFACE table $TABLE
75         ip -6 ro replace $eui64/128 dev $INTERFACE table $TABLE
76         ip -6 neigh add proxy $eui64 dev $uplink
77
78         # disable proxy NDP since we're handling this on userspace
79         # this should be the default, but better safe than sorry
80         echo 0 > /proc/sys/net/ipv6/conf/$INTERFACE/proxy_ndp
81 }
82
83 # pick a firewall profile per NIC, based on tags (and apply it)
84 function routed_setup_firewall {
85         ifprefix="synnefo:network:$INTERFACE_INDEX:"
86         for tag in $TAGS; do
87                 case ${tag#$ifprefix} in
88                 protected)
89                         chain=protected
90                 ;;
91                 unprotected)
92                         chain=unprotected
93                 ;;
94                 limited)
95                         chain=limited
96                 ;;
97                 esac
98         done
99
100         if [ "x$chain" != "x" ]; then
101                 iptables  -A FORWARD -o $INTERFACE -j $chain
102                 ip6tables -A FORWARD -o $INTERFACE -j $chain
103         fi
104 }
105
106 function init_ebtables {
107
108   ebtables -N $FROM
109   ebtables -A FORWARD -i $TAP -j $FROM
110   ebtables -N $TO
111   ebtables -A FORWARD -o $TAP -j $TO
112
113 }
114
115
116 function setup_ebtables {
117
118   # do not allow changes in ip-mac pair
119   if [ -n "$IP"]; then
120     ebtables -A $FROM --ip-source \! $IP -p ipv4 -j DROP
121   fi
122   ebtables -A $FROM -s \! $MAC -j DROP
123   #accept dhcp responses from host (nfdhcpd)
124   ebtables -A $TO -p ipv4 --ip-protocol=udp  --ip-destination-port=68 -j ACCEPT
125   # allow only packets from the same mac prefix
126   ebtables -A $TO -s \! $MAC/$MAC_MASK -j DROP
127 }
128
129 function setup_masq {
130
131   # allow packets from/to router (for masquerading)
132   # ebtables -A $TO -s $NODE_MAC -j ACCEPT
133   # ebtables -A INPUT -i $TAP -j $FROM
134   # ebtables -A OUTPUT -o $TAP -j $TO
135   return
136
137 }
138
139 function setup_nfdhcpd {
140         umask 022
141   FILE=$NFDHCPD_STATE_DIR/$INTERFACE
142   #IFACE is the interface from which the packet seems to arrive
143   #needed in bridged mode where the packets seems to arrive from the
144   #bridge and not from the tap
145         cat >$FILE <<EOF
146 INDEV=$INDEV
147 IP=$IP
148 MAC=$MAC
149 HOSTNAME=$INSTANCE
150 TAGS="$TAGS"
151 GATEWAY=$NETWORK_GATEWAY
152 SUBNET=$NETWORK_SUBNET
153 GATEWAY6=$NETWORK_GATEWAY6
154 SUBNET6=$NETWORK_SUBNET6
155 EUI64=$($MAC2EUI64 $MAC $NETWORK_SUBNET6 2>/dev/null)
156 EOF
157
158 }
159
160
161 source /etc/default/snf-network
162
163 TAP=$INTERFACE
164 FROM=FROM${TAP^^}
165 TO=TO${TAP^^}
166
167 clear_routed_setup_ipv4 > /dev/null 2>&1
168 clear_routed_setup_ipv6 > /dev/null 2>&1
169 clear_routed_setup_firewall > /dev/null 2>&1
170 clear_ebtables > /dev/null 2>&1
171 clear_nfdhcpd > /dev/null 2>&1
172
173 if [ "$MODE" = "routed" ]; then
174   TABLE=$LINK
175   ip link set $INTERFACE addr $TAP_CONSTANT_MAC up
176   INDEV=$INTERFACE
177   DROPDHCPREQCMD="iptables -A FORWARD -i $INTERFACE -p udp --dport 67 -j DROP"
178 elif [ "$MODE" = "bridged" ]; then
179   ip link set $INTERFACE up
180   brctl addif $BRIDGE $INTERFACE
181   INDEV=$BRIDGE
182   init_ebtables > /dev/null 2>&1
183   DROPDHCPREQCMD="ebtables -A $FROM -p ipv4 --ip-protocol udp --ip-destination-port 67 -j DROP"
184 fi
185
186
187 for tag in $NETWORK_TAGS; do
188   case $tag in
189   $IP_LESS_ROUTED_TAG)
190     routed_setup_ipv4 > /dev/null 2>&1
191     routed_setup_ipv6 > /dev/null 2>&1
192     routed_setup_firewall > /dev/null 2>&1
193   ;;
194   $NFDHCPD_TAG)
195     # Drop unicast BOOTP/DHCP packets
196     $DROPDHCPREQCMD > /dev/null 2>&1
197     setup_nfdhcpd > /dev/null 2>&1
198   ;;
199   $MAC_FILTERED_TAG)
200     setup_ebtables > /dev/null 2>&1
201   ;;
202   $MASQ_TAG)
203     setup_masq > /dev/null 2>&1
204   ;;
205   esac
206 done
207
208 exit 0