Automate config via hooks
[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
11
12 function clear_tap {
13
14  arptables -D OUTPUT -o $INTERFACE --opcode request -j mangle >/dev/null 2>&1
15  while ip rule del dev $INTERFACE; do :; done
16  iptables -D FORWARD -i $INTERFACE -p udp --dport 67 -j DROP 2>/dev/null
17
18
19 }
20
21 function routed_setup_ipv4 {
22
23         # mangle ARPs to come from the gw's IP
24         arptables -A OUTPUT -o $INTERFACE --opcode request -j mangle --mangle-ip-s    "$GATEWAY"
25
26         # route interface to the proper routing table
27         ip rule add dev $INTERFACE table $TABLE
28
29         # static route mapping IP -> INTERFACE
30         ip route replace $IP proto static dev $INTERFACE table $TABLE
31
32         # Enable proxy ARP
33         echo 1 > /proc/sys/net/ipv4/conf/$INTERFACE/proxy_arp
34 }
35
36 function routed_setup_ipv6 {
37         # Add a routing entry for the eui-64
38         prefix=$SUBNET6
39         uplink=$GATEWAY6
40         eui64=$($MAC2EUI64 $MAC $prefix)
41
42         while ip -6 rule del dev $INTERFACE; do :; done
43         ip -6 rule add dev $INTERFACE table $TABLE
44         ip -6 ro replace $eui64/128 dev $INTERFACE table $TABLE
45         ip -6 neigh add proxy $eui64 dev $uplink
46
47         # disable proxy NDP since we're handling this on userspace
48         # this should be the default, but better safe than sorry
49         echo 0 > /proc/sys/net/ipv6/conf/$INTERFACE/proxy_ndp
50 }
51
52 # pick a firewall profile per NIC, based on tags (and apply it)
53 function routed_setup_firewall {
54         ifprefix="synnefo:network:$INTERFACE_INDEX:"
55         for tag in $TAGS; do
56                 case ${tag#$ifprefix} in
57                 protected)
58                         chain=protected
59                 ;;
60                 unprotected)
61                         chain=unprotected
62                 ;;
63                 limited)
64                         chain=limited
65                 ;;
66                 esac
67         done
68
69         # Flush any old rules. We have to consider all chains, since
70         # we are not sure the instance was on the same chain, or had the same
71         # tap interface.
72         for oldchain in protected unprotected limited; do
73                 iptables  -D FORWARD -o $INTERFACE -j $oldchain 2>/dev/null
74                 ip6tables -D FORWARD -o $INTERFACE -j $oldchain 2>/dev/null
75         done
76
77         if [ "x$chain" != "x" ]; then
78                 iptables  -A FORWARD -o $INTERFACE -j $chain
79                 ip6tables -A FORWARD -o $INTERFACE -j $chain
80         fi
81 }
82
83 function setup_nfdhcpd {
84         umask 022
85   FILE=$NFDHCPD_STATE_DIR/$INTERFACE
86   #IFACE is the interface from which the packet seems to arrive
87   #needed in bridged mode where the packets seems to arrive from the
88   #bridge and not from the tap
89         cat >$FILE <<EOF
90 IFACE=$1
91 IP=$IP
92 MAC=$MAC
93 HOSTNAME=$INSTANCE
94 TAGS="$TAGS"
95 EOF
96 if [ -n "$GATEWAY" ]; then
97  echo GATEWAY=$GATEWAY >> $FILE
98 fi
99 if [ -n "$SUBNET" ]; then
100  echo SUBNET=$SUBNET >> $FILE
101 fi
102 if [ -n "$GATEWAY6" ]; then
103  echo GATEWAY6=$GATEWAY6 >> $FILE
104 fi
105 if [ -n "$SUBNET6" ]; then
106  echo SUBNET6=$SUBNET6 >> $FILE
107 fi
108
109 }
110
111 function clear_ebtables {
112   TAP=$INTERFACE
113   FROM=FROM${TAP^^}
114   TO=TO${TAP^^}
115
116   exist=$(ebtables -L | grep $TAP)
117
118   if [ ! -z "$exist" ]; then
119     ebtables -D INPUT -i $TAP -j $FROM
120     ebtables -D FORWARD -i $TAP -j $FROM
121     ebtables -D FORWARD -o $TAP -j $TO
122     ebtables -D OUTPUT -o $TAP -j $TO
123
124     ebtables -X $FROM
125     ebtables -X $TO
126   fi
127 }
128
129 function setup_ebtables {
130   TAP=$INTERFACE
131   FROM=FROM${TAP^^}
132   TO=TO${TAP^^}
133
134   ebtables -N $FROM
135   # do not allow changes in ip-mac pair
136   ebtables -A $FROM --ip-source \! $IP -p ipv4 -j DROP
137   ebtables -A $FROM -s \! $MAC -j DROP
138   ebtables -A FORWARD -i $TAP -j $FROM
139   ebtables -N $TO
140   ebtables -A FORWARD -o $TAP -j $TO
141   #accept dhcp responses from host (nfdhcpd)
142   ebtables -A $TO -p ipv4 --ip-protocol=udp  --ip-destination-port=68 -j ACCEPT
143   if [ "$TYPE" == "private" ]; then
144     if [ ! -z "$GATEWAY" -a $ENABLE_MASQ ]; then
145       # allow packets from/to router (for masquerading
146       ebtables -A $TO -s $ROUTER_MAC -j ACCEPT
147       ebtables -A INPUT -i $TAP -j $FROM
148       ebtables -A OUTPUT -o $TAP -j $TO
149     fi
150     # allow only packets from the same mac prefix
151     ebtables -A $TO -s \! $MAC/$MAC_MASK -j DROP
152   fi
153 }
154
155
156
157 DEFAULT=/etc/default/snf-network
158 source $DEFAULT
159 source $CONF
160
161 NODEINFRAFILE=$SHAREDDIR/infra/$(hostname)
162
163 if [ -e "$NODEINFRAFILE" ]; then
164   source $NODEINFRAFILE
165 fi
166
167 CLUSTERINFRAFILE=$SHAREDDIR/infra/cluster
168
169 if [ -e "$CLUSTERINFRAFILE" ]; then
170   source $CLUSTERINFRAFILE
171 fi
172
173 NETFILE=$SHAREDDIR/networks/$NETWORK
174
175 if [ -e "$NETFILE" ]; then
176   source $NETFILE
177 fi
178
179 if [ "$MODE" = "routed" ]; then
180   TABLE=rt_$NETWORK
181         # special proxy-ARP/NDP routing mode
182   clear_tap
183         # use a constant predefined MAC address for the tap
184         ip link set $INTERFACE addr $TAP_CONSTANT_MAC
185         # bring the tap up
186         ifconfig $INTERFACE 0.0.0.0 up
187
188         # Drop unicast BOOTP/DHCP packets
189         iptables -A FORWARD -i $INTERFACE -p udp --dport 67 -j DROP
190
191         routed_setup_ipv4
192         routed_setup_ipv6
193         routed_setup_firewall
194         setup_nfdhcpd $INTERFACE
195   clear_ebtables >/dev/null 2>&1
196 elif [ "$MODE" = "bridged" ]; then
197   clear_tap
198   clear_ebtables >/dev/null 2>&1
199         ifconfig $INTERFACE 0.0.0.0 up
200         brctl addif $BRIDGE $INTERFACE
201         setup_nfdhcpd $BRIDGE
202   setup_ebtables
203 fi