ipw 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. #!/bin/bash
  2. # Copyright (C) 2013 Artyom A Anikeev <anikeev@ut.mephi.ru> 0xB5385841,
  3. # Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. CMD="$1"; shift;
  18. DEFAULT_BONDING_MODE='balance-tlb'
  19. modprobe bonding
  20. if lockfile-check /run/ipw; then
  21. eerror 'Another "ipw" instance is already running'
  22. exit -1
  23. fi
  24. trap 'lockfile-remove /run/ipw' SIGINT SIGTERM SIGHUP SIGQUIT SIGALRM SIGILL SIGABRT SIGPIPE EXIT
  25. lockfile-create /run/ipw || exit
  26. eerror() {
  27. echo "$@" >&2
  28. }
  29. newconfig_open() {
  30. echo -n > "$NEWCONFIG_TMPPATH"
  31. }
  32. newconfig_write() {
  33. LINE="$1"; shift;
  34. [[ "$NEWCONFIG" -eq 0 ]] && return
  35. echo "$LINE" >> "$NEWCONFIG_TMPPATH"
  36. }
  37. newconfig_commit() {
  38. rm -f "$CONFIG_PATH"
  39. mv "$NEWCONFIG_TMPPATH" "$CONFIG_PATH"
  40. }
  41. newconfig_push() {
  42. BUFNUM="$1"; shift;
  43. LINE="$1"; shift;
  44. BUF[$BUFNUM]="${BUF[$BUFNUM]}
  45. $LINE"
  46. }
  47. newconfig_pushpopall() {
  48. BUFNUMTO="$1"; shift;
  49. BUFNUMFROM="$1"; shift;
  50. newconfig_push "$BUFNUMTO" "${BUF[$BUFNUMFROM]}"
  51. newconfig_popall "$BUFNUMFROM"
  52. }
  53. newconfig_popall() {
  54. BUFNUM="$1"; shift;
  55. BUF[$BUFNUM]=""
  56. }
  57. newconfig_popallwrite() {
  58. BUFNUM="$1"; shift;
  59. newconfig_write "${BUF[$BUFNUM]}"
  60. BUF[$BUFNUM]=""
  61. }
  62. # INPUT: 10.2:thor.ext; OUTPUT: environments: VLAN, SUBVLAN, BRNAME
  63. parse_vlan_subvlan_bridge() {
  64. VLAN_N_BRIDGE="$1"; shift
  65. if [[ "${VLAN_N_BRIDGE:0:1}" = ":" ]]; then
  66. VLAN=""
  67. SUBVLAN=""
  68. VLANNAME=""
  69. BRNAME="${VLAN_N_BRIDGE:1}"
  70. else
  71. # Splitting by ":"
  72. WORDS=( ${VLAN_N_BRIDGE//[:]/ } )
  73. # The second word defines interface name. If it's empty, "vlan$VLAN.$SUBVLAN" is used.
  74. VLANNAME="${WORDS[0]}"
  75. BRNAME="${WORDS[1]}"
  76. # Splitting by "."
  77. WORDS=( ${VLANNAME//[.]/ } )
  78. # The second word defines subvlan (1q-in-1q) if it's used. It's empty if no subvlan is used.
  79. VLAN="${WORDS[0]}"
  80. SUBVLAN="${WORDS[1]}"
  81. fi
  82. # Checking if no "vlan(.subvlan)?" is set
  83. if ! [[ "${VLAN_N_BRIDGE: -1}" = ":" ]]; then
  84. # Setting default values
  85. [[ "$SUBVLAN" = "" ]] && BRNAME="${BRNAME:-vlan${VLAN}}" || BRNAME="${BRNAME:-vlan${VLAN}.${SUBVLAN}}"
  86. fi
  87. return;
  88. }
  89. declare -A get_brname_byslave_assoc
  90. for VLAN_N_BRIDGE in $(find /sys/devices/virtual/net -wholename '*/brif/*' | awk -F '/' '{print $8":"$6}'); do
  91. oldIFS="$IFS"; IFS=':'; words=($VLAN_N_BRIDGE); IFS="$oldIFS"
  92. get_brname_byslave_assoc[${words[0]}]=${words[1]}
  93. done
  94. get_brname_byslave() {
  95. _SLAVE="$1"; shift
  96. echo ${get_brname_byslave_assoc[$_SLAVE]}
  97. }
  98. get_vlan_n_bridges() {
  99. awk '{if(NR>2) if( system( "[ -d /sys/devices/virtual/net/*/brif/"$1" ] " ) != 0 ) print $1":"}' < /proc/1/net/vlan/config
  100. find /sys/devices/virtual/net -wholename '*/brif' -empty | awk -F '/' '{print ":"$6}'
  101. find /sys/devices/virtual/net -wholename '*/brif/*' | awk -F '/' '{print $8":"$6}'
  102. }
  103. iface_isexists() {
  104. _IFACE="$1"; shift;
  105. [ -e /sys/devices/virtual/net/"$_IFACE" ]
  106. return $?
  107. }
  108. ip_cmds() {
  109. _IFACE="$1"; shift
  110. ip addr flush dev "$_IFACE"
  111. IP_CMDS_VARIABLE="${_IFACE//[.]/_}_IP"
  112. IP_CMDS_VARIABLE="${IP_CMDS_VARIABLE}[@]"
  113. for IP_CMD in "${!IP_CMDS_VARIABLE}"; do
  114. [[ "$IP_CMD" != "" ]] &&
  115. ip $IP_CMD dev "$_IFACE"
  116. done
  117. }
  118. case "$CMD" in
  119. down)
  120. IPW_CONFIG_PATH=/dev/null
  121. CMD='fix'
  122. ;;
  123. esac
  124. IPW_CONFIG_PATH="${IPW_CONFIG_PATH:-/etc/ipw.conf}"
  125. BRIDGE_FORWARD_DELAY=0
  126. source "$IPW_CONFIG_PATH"
  127. NEWCONFIG_TMPPATH="/tmp/.~ipw"
  128. NEWCONFIG=0
  129. case "$CMD" in
  130. add1qif) #allow to add slave interface in bonding
  131. NEWCONFIG=1 # we need to update the config after the command
  132. NEW_D1Q_IFACE="$1"; shift
  133. NEW_SLAVE="$1"; shift
  134. # checking for duplicated slaves or d1q_ifaces
  135. D1Q_IFACE_USED=0
  136. for D1Q_IFACE in ${D1Q_IFACES[@]}; do
  137. if [[ "$D1Q_IFACE" = "$NEW_D1Q_IFACE" ]]; then
  138. D1Q_IFACE_USED=1
  139. fi
  140. SLAVES_VARIABLE="${D1Q_IFACE}_SLAVES"
  141. SLAVES_VARIABLE="${SLAVES_VARIABLE//[.]/_}[@]"
  142. for SLAVE in "${!SLAVES_VARIABLE}"; do
  143. if [[ "$SLAVE" = "$NEW_SLAVE" ]]; then
  144. eerror "This interface have already been enslaved"
  145. exit -1
  146. fi
  147. done
  148. done
  149. if [[ $D1Q_IFACE_USED -eq 0 ]]; then
  150. D1Q_IFACES[ ${#D1Q_IFACES} ]="$NEW_D1Q_IFACE"
  151. fi
  152. SLAVES_VARIABLE="${NEW_D1Q_IFACE}_SLAVES"
  153. SLAVES_VARIABLE="${SLAVES_VARIABLE//[.]/_}"
  154. eval "${SLAVES_VARIABLE}[\${#${SLAVES_VARIABLE}}]=\"$NEW_SLAVE\""
  155. ;;
  156. del1qif)
  157. ;;
  158. addbrif) #allow to add bridge/vlan in bonding
  159. NEWCONFIG=1 # we need to update the config after the command
  160. NEW_D1Q_IFACE="$1"; shift
  161. NEW_VLAN_SUBVLAN="$1"; shift
  162. NEW_BRIDGE="$1"; shift
  163. [[ -z $NEW_BRIDGE ]] && NEW_VLAN_N_BRIDGE="${NEW_VLAN_SUBVLAN}" || NEW_VLAN_N_BRIDGE="${NEW_VLAN_SUBVLAN}:${NEW_BRIDGE}"
  164. D1Q_IFACE_USED=0
  165. for D1Q_IFACE in ${D1Q_IFACES[@]}; do
  166. if [[ "$D1Q_IFACE" = "$NEW_D1Q_IFACE" ]]; then
  167. D1Q_IFACE_USED=1
  168. break;
  169. fi
  170. done
  171. parse_vlan_subvlan_bridge "${NEW_VLAN_N_BRIDGE}"
  172. NEW_VLAN=$VLAN
  173. NEW_SUBVLAN=$SUBVLAN
  174. if [[ $D1Q_IFACE_USED -eq 0 ]]; then
  175. eerror "There's no such interface: $NEW_D1Q_IFACE"
  176. exit -1
  177. fi
  178. VLAN_N_BRIDGE_VARIABLE="${NEW_D1Q_IFACE}_VLAN_N_BRIDGES"
  179. VLAN_N_BRIDGE_VARIABLE="${VLAN_N_BRIDGE_VARIABLE//[.]/_}[@]"
  180. for VLAN_N_BRIDGE in "${!VLAN_N_BRIDGE_VARIABLE}"; do
  181. parse_vlan_subvlan_bridge "${VLAN_N_BRIDGE}"
  182. if [[ "$VLAN" = "$NEW_VLAN" && "$SUBVLAN" = "$NEW_SUBVLAN" ]]; then
  183. eerror "This vlan is alredy used"
  184. exit -1
  185. fi
  186. done
  187. VLAN_N_BRIDGE_VARIABLE="${NEW_D1Q_IFACE}_VLAN_N_BRIDGES"
  188. VLAN_N_BRIDGE_VARIABLE="${VLAN_N_BRIDGE_VARIABLE//[.]/_}"
  189. eval "${VLAN_N_BRIDGE_VARIABLE}[\${#${VLAN_N_BRIDGE_VARIABLE}}]=\"$NEW_VLAN_N_BRIDGE\""
  190. #D1Q_IFACES[ ${#D1Q_IFACES}]
  191. ;;
  192. delbrif)
  193. ;;
  194. addbr) #allow to add bridge without interfaces
  195. NEWCONFIG=1 # we need to update the config after the command
  196. NEW_D1Q_IFACE="$1"; shift
  197. NEW_BRIDGE="$1"; shift
  198. VLAN_N_BRIDGE_VARIABLE="${NEW_D1Q_IFACE}_VLAN_N_BRIDGES"
  199. VLAN_N_BRIDGE_VARIABLE="${VLAN_N_BRIDGE_VARIABLE//[.]/_}"
  200. eval "${VLAN_N_BRIDGE_VARIABLE}[\${#${VLAN_N_BRIDGE_VARIABLE}}]=\":${NEW_BRIDGE}\""
  201. ;;
  202. delbr)
  203. ;;
  204. addif) #allow to add interface without bridging
  205. ;;
  206. delif)
  207. ;;
  208. addipcmd) #allow to add ip commnds for bridges/vlans
  209. NEWCONFIG=1 # we need to update the config after the command
  210. NEW_BRIDGE="$1"; shift
  211. NEW_IP_CMD="$@"
  212. if [[ "${NEW_BRIDGE}" != "" ]]; then
  213. # Getting commands for "ip"
  214. IP_CMDS_VARIABLE="${NEW_BRIDGE//[.]/_}_IP"
  215. IP_CMDS_VARIABLE="${IP_CMDS_VARIABLE}"
  216. eval "${IP_CMDS_VARIABLE}[\${#${IP_CMDS_VARIABLE}}]=\"$NEW_IP_CMD\""
  217. fi
  218. ;;
  219. delipcmd)
  220. NEWCONFIG=1 # we need to update the config after the command
  221. NEW_BRIDGE="$1"; shift
  222. NEW_IP_CMD="$@"
  223. if [[ "${NEW_BRIDGE}" != "" ]]; then
  224. IP_CMDS_VARIABLE="${NEW_BRIDGE//[.]/_}_IP"
  225. IP_CMDS_VARIABLE="${IP_CMDS_VARIABLE}"
  226. i=0
  227. CMD_founded=0
  228. for IP_CMD in "${!IP_CMDS_VARIABLE}"; do
  229. if [[ "$IP_CMD" = "$NEW_IP_CMD" ]]; then
  230. CMD_founded=1
  231. else
  232. TMP[$i]=$IP_CMD
  233. (( i++ ))
  234. fi
  235. done
  236. if [[ $CMD_founded -eq 0 ]]; then
  237. eerror "There's no such command"
  238. exit -1
  239. fi
  240. i=0
  241. for IP_CMD in "${!TMP}"; do
  242. IP_CMDS_VARIABLE[$i]=$IP_CMD
  243. (( i++ ))
  244. done
  245. #eval "${IP_CMDS_VARIABLE}[\${#${IP_CMDS_VARIABLE}}]=\"$NEW_IP_CMD\""
  246. #echo $IP_CMDS_VARIABLE
  247. fi ;;
  248. fix) #fix all interfaces to config state
  249. #brctl addif bond0 eth2
  250. if [[ "$IPW_DEBUG" -ge "2" ]]; then
  251. cat "$IPW_CONFIG_PATH" > /tmp/ipw.conf-fix.$(date +'%Y%m%d%H%M%S')
  252. fi
  253. if [[ "$IPW_CONFIG_PATH" != "/dev/null" ]]; then
  254. if [[ "$(cat $IPW_CONFIG_PATH 2>/dev/null)" = "" ]]; then
  255. eerror "Empty config file"
  256. exit -1
  257. fi
  258. fi
  259. #GETTING INFORMATION ABOUT LXC INTERFACES IN BRIDGES
  260. if [[ "$LXC_DIR" != "" ]]; then
  261. LXC_BRIDGE_SLAVES=($(cat /srv/lxc/*/config | tr -d " \t" | awk -F '=' '{if($1=="lxc.network.link") {BRIDGE=$2}; if($1=="lxc.network.veth.pair") {if(BRIDGE!="") {print $2":"BRIDGE; BRIDGE=""}} }'))
  262. fi
  263. #REMOVING UNNECESSARY D1Q
  264. OLD_D1Q_IFACES="`cat /sys/class/net/bonding_masters`"
  265. for OLD_D1Q_IFACE in ${OLD_D1Q_IFACES[@]}; do
  266. D1Q_IS_USED=0
  267. OLD_SLAVES="`cat /sys/class/net/"$OLD_D1Q_IFACE"/bonding/slaves`"
  268. for D1Q_IFACE in ${D1Q_IFACES[@]}; do
  269. if [[ "$D1Q_IFACE" == "$OLD_D1Q_IFACE" ]]; then #let's kick out useless slaves
  270. SLAVES_VARIABLE="${D1Q_IFACE}_SLAVES"
  271. SLAVES_VARIABLE="${SLAVES_VARIABLE//[.]/_}[@]"
  272. for OLD_SLAVE in ${OLD_SLAVES[@]}; do
  273. SLAVE_IS_USED=0
  274. for SLAVE in "${!SLAVES_VARIABLE}"; do
  275. if [[ "$SLAVE" == "$OLD_SLAVE" ]]; then
  276. SLAVE_IS_USED=1
  277. break;
  278. fi
  279. done
  280. if [[ "$SLAVE_IS_USED" == 0 ]]; then
  281. echo "-$OLD_SLAVE" > /sys/class/net/"$OLD_D1Q_IFACE"/bonding/slaves
  282. fi
  283. done
  284. D1Q_IS_USED=1
  285. break;
  286. fi
  287. done
  288. if [[ "$D1Q_IS_USED" == 0 ]]; then #let's kick out useless d1q
  289. echo "-$OLD_D1Q_IFACE" > /sys/class/net/bonding_masters
  290. fi
  291. done
  292. #REMEMBERING REQUIRED INTERFACES
  293. declare -A REQUIRED_FULLNAME_HASH
  294. declare -A REQUIRED_BRNAME_HASH
  295. declare -A REQUIRED_IFACENAME_HASH
  296. for D1Q_IFACE_TMP in ${D1Q_IFACES[@]}; do #we should keep slave ifaces
  297. VLAN_N_BRIDGE_VARIABLE="${D1Q_IFACE_TMP}_VLAN_N_BRIDGES"
  298. VLAN_N_BRIDGE_VARIABLE="${VLAN_N_BRIDGE_VARIABLE//[.]/_}[@]"
  299. for VLAN_N_BRIDGE in "${!VLAN_N_BRIDGE_VARIABLE}"; do
  300. parse_vlan_subvlan_bridge "${VLAN_N_BRIDGE}"
  301. REQUIRED_FULLNAME_HASH["$D1Q_IFACE_TMP"."$VLAN_N_BRIDGE"]="$D1Q_IFACE_TMP"."$VLAN_N_BRIDGE"
  302. if [[ "$BRNAME" != "" ]]; then
  303. REQUIRED_BRNAME_HASH["$BRNAME"]="$BRNAME"
  304. fi
  305. if [[ "$VLANNAME" != "" ]]; then
  306. REQUIRED_IFACENAME_HASH["$VLANNAME"]="$VLANNAME"
  307. REQUIRED_IFACENAME_HASH["$D1Q_IFACE_TMP"."$VLAN"]="$D1Q_IFACE_TMP"."$VLAN"
  308. fi
  309. done
  310. done
  311. for LXCIF_N_BRIDGE in ${LXC_BRIDGE_SLAVES[@]}; do
  312. REQUIRED_FULLNAME_HASH["$LXCIF_N_BRIDGE"]="$LXCIF_N_BRIDGE"
  313. done
  314. #CONFIGURING AND REMEMBERING ACCESS INTERFACES (NOT D1Q)
  315. for ACCESS_IFACE in ${ACCESS_IFACES[@]}; do
  316. oldIFS="$IFS"; IFS=":"
  317. WORDS=(${ACCESS_IFACE})
  318. IFS="$oldIFS"
  319. IFACE="${WORDS[0]}"
  320. BRNAME="${WORDS[1]}"
  321. if [[ "$BRNAME" != "" ]]; then
  322. REQUIRED_BRNAME_HASH["$BRNAME"]="$BRNAME"
  323. if ! iface_isexists "$BRNAME"; then
  324. ip link add "$BRNAME" type bridge
  325. ip link set dev "$BRNAME" up
  326. fi
  327. ip link set "$IFACE" master "$BRNAME"
  328. ip_cmds "$BRNAME"
  329. fi
  330. REQUIRED_IFACENAME_HASH["$IFACE"]="$IFACE"
  331. ip_cmds "$IFACE"
  332. done
  333. #REMOVING UNNECESSARY BRIDGES AND VLANS
  334. OLD_VLAN_N_BRIDGES=(`get_vlan_n_bridges`)
  335. for LINE in ${OLD_VLAN_N_BRIDGES[@]}; do
  336. #echo ITERATION
  337. parse_vlan_subvlan_bridge "$LINE"
  338. OLD_BRNAME="$BRNAME"
  339. OLD_VLANNAME="$VLANNAME"
  340. IS_SLAVE=0
  341. BRIDGE_IN_USE=0
  342. IFACE_IN_USE=0
  343. VLAN_N_BRIDGE_IN_USE=0
  344. if [[ "${REQUIRED_FULLNAME_HASH[$LINE]}" != "" ]]; then
  345. BRIDGE_IN_USE=1
  346. IFACE_IN_USE=1
  347. VLAN_N_BRIDGE_IN_USE=1
  348. else
  349. [[ "$OLD_BRNAME" != "" ]] &&
  350. if [[ "${REQUIRED_BRNAME_HASH[$OLD_BRNAME]}" != "" ]]; then
  351. BRIDGE_IN_USE=1
  352. fi
  353. [[ "$OLD_VLANNAME" != "" ]] &&
  354. if [[ "${REQUIRED_IFACENAME_HASH[$OLD_VLANNAME]}" != "" ]]; then
  355. IFACE_IN_USE=1
  356. fi
  357. fi
  358. if [[ "$BRIDGE_IN_USE" = 0 ]]; then
  359. [[ "$OLD_BRNAME" != '' ]] &&
  360. ip link delete "$OLD_BRNAME"
  361. fi
  362. if [[ "$IFACE_IN_USE" = 0 ]]; then
  363. if [[ "$OLD_VLANNAME" != '' ]]; then
  364. ip link set "$OLD_VLANNAME" nomaster
  365. ip link delete "$OLD_VLANNAME"
  366. fi
  367. fi
  368. done
  369. #CREATING OF NECESSARY D1Q
  370. for D1Q_IFACE in ${D1Q_IFACES[@]}; do
  371. # Fixing bond-ifaces if exists
  372. SLAVES_VARIABLE="${D1Q_IFACE}_SLAVES"
  373. SLAVES_VARIABLE="${SLAVES_VARIABLE//[.]/_}[@]"
  374. MODE_VARIABLE="${D1Q_IFACE}_MODE"
  375. MODE="${!MODE_VARIABLE}"; [[ "$MODE" = "" ]] && MODE="$DEFAULT_BONDING_MODE"
  376. D1Q_EXISTS=0
  377. for OLD_D1Q_IFACE in ${OLD_D1Q_IFACES[@]}; do
  378. if [[ "$D1Q_IFACE" == "$OLD_D1Q_IFACE" ]]; then #it's here. Let's fix it.
  379. OLD_SLAVES="`cat /sys/class/net/"$OLD_D1Q_IFACE"/bonding/slaves`"
  380. OLD_BONDING_MODE=(`cat /sys/class/net/"$OLD_D1Q_IFACE"/bonding/mode`)
  381. if [ "${OLD_BONDING_MODE[0]}" != "${MODE}" -a "${OLD_BONDING_MODE[1]}" != "${MODE}" ]; then
  382. for OLD_SLAVE in ${OLD_SLAVES[@]}; do
  383. echo "-$OLD_SLAVE" > /sys/class/net/"$OLD_D1Q_IFACE"/bonding/slaves
  384. done
  385. ip link set dev "$OLD_D1Q_IFACE" down
  386. echo "$MODE" > /sys/class/net/"$OLD_D1Q_IFACE"/bonding/mode
  387. OLD_SLAVES=()
  388. fi
  389. for SLAVE in "${!SLAVES_VARIABLE}"; do
  390. SLAVE_EXISTS=0
  391. for OLD_SLAVE in ${OLD_SLAVES[@]}; do
  392. if [[ "$SLAVE" == "$OLD_SLAVE" ]]; then
  393. SLAVE_EXISTS=1
  394. break;
  395. fi
  396. done
  397. if [[ "$SLAVE_EXISTS" == 0 ]]; then
  398. ip link set dev "$SLAVE" down #enslaved int should be shutted down
  399. echo "+$SLAVE" > /sys/class/net/"$D1Q_IFACE"/bonding/slaves
  400. fi
  401. done
  402. D1Q_EXISTS=1
  403. break;
  404. fi
  405. done
  406. # Creating bond-ifaces
  407. if [[ "$D1Q_EXISTS" == 0 ]]; then #make all
  408. echo "+$D1Q_IFACE" > /sys/class/net/bonding_masters 2>/dev/null
  409. if [[ -d /sys/class/net/"$D1Q_IFACE"/bonding ]]; then
  410. echo "$MODE" > /sys/class/net/"$D1Q_IFACE"/bonding/mode
  411. fi
  412. for SLAVE in "${!SLAVES_VARIABLE}"; do
  413. ip link set dev "$SLAVE" down #enslaved int should be shutted down
  414. echo "+$SLAVE" > /sys/class/net/"$D1Q_IFACE"/bonding/slaves
  415. done
  416. fi
  417. ip link set dev "$D1Q_IFACE" up
  418. for SLAVE in "${!SLAVES_VARIABLE}"; do #slave starts after bond
  419. ip link set dev "$SLAVE" up
  420. done
  421. VLAN_N_BRIDGE_VARIABLE="${D1Q_IFACE}_VLAN_N_BRIDGES"
  422. VLAN_N_BRIDGE_VARIABLE="${VLAN_N_BRIDGE_VARIABLE//[.]/_}[@]"
  423. #CREATING NECESSARY BRIDGES AND VLANS
  424. for VLAN_N_BRIDGE in "${!VLAN_N_BRIDGE_VARIABLE}"; do
  425. parse_vlan_subvlan_bridge "${VLAN_N_BRIDGE}"
  426. FULL_VLAN_NAME="$D1Q_IFACE"."$VLANNAME"
  427. #VLAN STUFF
  428. if [[ "$VLAN" != "" ]]; then
  429. if ! iface_isexists "$FULL_VLAN_NAME"; then #should we create a new vlan?
  430. if [[ "$SUBVLAN" != "" ]]; then #is it subvlan?
  431. FULL_PARVLAN_NAME="$D1Q_IFACE"."$VLAN"
  432. if ! iface_isexists "$FULL_PARVLAN_NAME"; then #should we create a new parent vlan?
  433. ip link add link "$D1Q_IFACE" name "$FULL_PARVLAN_NAME" type vlan id "$VLAN" #vlan in bond
  434. ip link set dev "$FULL_PARVLAN_NAME" up
  435. fi
  436. ip link add link "$FULL_PARVLAN_NAME" name "$FULL_VLAN_NAME" type vlan id "$SUBVLAN" #subvlan in vlan
  437. ip link set dev "$FULL_VLAN_NAME" mtu 1496
  438. ip link set dev "$FULL_VLAN_NAME" up
  439. else
  440. ip link add link "$D1Q_IFACE" name "$FULL_VLAN_NAME" type vlan id "$VLANNAME" #vlan in bond
  441. ip link set dev "$FULL_VLAN_NAME" up
  442. fi
  443. fi
  444. ip_cmds "$FULL_VLAN_NAME"
  445. fi
  446. #BRIDGE STUFF
  447. if [[ "$BRNAME" != "" ]]; then
  448. if ! iface_isexists "$BRNAME"; then #do this bridge exists?
  449. ip link add "$BRNAME" type bridge
  450. echo "$BRIDGE_FORWARD_DELAY" > /sys/devices/virtual/net/"$BRNAME"/bridge/forward_delay
  451. ip link set dev "$BRNAME" up
  452. fi
  453. if [[ "$VLAN" != "" ]]; then
  454. OLD_BRNAME="`get_brname_byslave "$FULL_VLAN_NAME"`"
  455. if [[ "$OLD_BRNAME" = "" ]]; then #is this vlan have been already enslaved?
  456. ip link set "$FULL_VLAN_NAME" master "$BRNAME"
  457. else
  458. if [[ "$BRNAME" != "$OLD_BRNAME" ]]; then
  459. ip link set "$FULL_VLAN_NAME" nomaster
  460. ip link set "$FULL_VLAN_NAME" master "$BRNAME"
  461. fi
  462. fi
  463. fi
  464. ip_cmds "$BRNAME"
  465. fi
  466. done
  467. done
  468. # ADDING LXC IFACES TO BRIDGES IF REQUIRED
  469. for LXCIF_N_BRIDGE in ${LXC_BRIDGE_SLAVES[@]}; do
  470. parse_vlan_subvlan_bridge "$LINE"
  471. brctl addif "$BRNAME" "$VLANNAME" 2>/dev/null
  472. done
  473. ;;
  474. *)
  475. ;;
  476. esac
  477. newconfig_open
  478. newconfig_write "#"
  479. newconfig_write ""
  480. newconfig_write "D1Q_IFACES=("
  481. for D1Q_IFACE in ${D1Q_IFACES[@]}; do
  482. newconfig_write " $D1Q_IFACE"
  483. newconfig_push 128 "${D1Q_IFACE}_SLAVES=("
  484. haveaslave=0
  485. SLAVES_VARIABLE="${D1Q_IFACE}_SLAVES"
  486. SLAVES_VARIABLE="${SLAVES_VARIABLE//[.]/_}[@]"
  487. for SLAVE in "${!SLAVES_VARIABLE}"; do
  488. newconfig_push 128 " $SLAVE";
  489. haveaslave=1
  490. done
  491. newconfig_push 128 ")"
  492. # If there're no slaves then don't write anything about them
  493. [[ $haveaslave -ne 0 ]] && newconfig_pushpopall 1 128 || newconfig_popall 128
  494. VLAN_N_BRIDGE_VARIABLE="${D1Q_IFACE}_VLAN_N_BRIDGES"
  495. VLAN_N_BRIDGE_VARIABLE="${VLAN_N_BRIDGE_VARIABLE//[.]/_}[@]"
  496. newconfig_push 1 "${D1Q_IFACE}_VLAN_N_BRIGES=("
  497. for VLAN_N_BRIDGE in "${!VLAN_N_BRIDGE_VARIABLE}"; do
  498. newconfig_push 1 " ${VLAN_N_BRIDGE}"
  499. parse_vlan_subvlan_bridge "${VLAN_N_BRIDGE}"
  500. # Checking if no "vlan(.subvlan)?" is set
  501. if [[ "${BRNAME}" != "" ]]; then
  502. #echo $BRNAME
  503. # Getting commands for "ip"
  504. IP_CMDS_VARIABLE="${BRNAME//[.]/_}_IP"
  505. newconfig_push 128 "${IP_CMDS_VARIABLE}=("
  506. IP_CMDS_VARIABLE="${IP_CMDS_VARIABLE}[@]"
  507. hasanIP_CMD=0
  508. for IP_CMD in "${!IP_CMDS_VARIABLE}"; do
  509. newconfig_push 128 " \"$IP_CMD\""
  510. #echo ip $IP_CMD dev $BRNAME
  511. hasanIP_CMD=1
  512. done
  513. newconfig_push 128 ")"
  514. newconfig_push 128 ""
  515. [[ $hasanIP_CMD -ne 0 ]] && newconfig_pushpopall 2 128 || newconfig_popall 128
  516. else
  517. # Getting commands for "ip"
  518. #echo OK
  519. IP_CMDS_VARIABLE="vlan${VLANNAME//[.]/_}_IP"
  520. newconfig_push 128 "${IP_CMDS_VARIABLE}=("
  521. IP_CMDS_VARIABLE="${IP_CMDS_VARIABLE}[@]"
  522. hasanIP_CMD=0
  523. for IP_CMD in "${!IP_CMDS_VARIABLE}"; do
  524. newconfig_push 128 " \"$IP_CMD\""
  525. #echo ip $IP_CMD dev $VLANNAME
  526. hasanIP_CMD=1
  527. done
  528. newconfig_push 128 ")"
  529. newconfig_push 128 ""
  530. [[ $hasanIP_CMD -ne 0 ]] && newconfig_pushpopall 2 128 || newconfig_popall 128
  531. fi
  532. printf "br: %-16s vlan:%5s subvlan:%5s\n" "$BRNAME" "$VLAN" "$SUBVLAN"
  533. done
  534. newconfig_push 1 ")"
  535. done
  536. for ACCESS_IFACE in ${ACCESS_IFACES[@]}; do
  537. oldIFS="$IFS"; IFS=":"
  538. WORDS=(${ACCESS_IFACE})
  539. IFS="$oldIFS"
  540. IFACE="${WORDS[0]}"
  541. BRNAME="${WORDS[1]}"
  542. printf "access: %-12s bridge: %-8s\n" "$IFACE" "$BRNAME"
  543. done
  544. newconfig_write ")"
  545. newconfig_popallwrite 1
  546. newconfig_popallwrite 2
  547. newconfig_popallwrite 3
  548. #[[ $NEWCONFIG -ne 0 ]] && newconfig_commit
  549. exit 0