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