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