--- /dev/null
+#!/bin/bash
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# Copyright (C) 2012 IPFire Network Development Team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+MACVLAN_PORT_INTERFIX="mv"
+
+function macvlan_create() {
+ local device=${1}
+ assert isset device
+
+ local parent=${2}
+ assert isset parent
+
+ local address=${3}
+ assert ismac address
+
+ # Check if the parent device exists.
+ if ! device_exists ${parent}; then
+ log ERROR "macvlan: parent device '${parent}' does not exist"
+ return ${EXIT_ERROR}
+ fi
+
+ # Check if the device we want to create does not already exist.
+ if device_exists ${device}; then
+ log ERROR "macvlan: device '${device}' already exists"
+ return ${EXIT_ERROR}
+ fi
+
+ # The macvlan device cannot be created, when the parent device
+ # is attached to a bridge. So we detach the parent device and
+ # reattach it again.
+ local bridge
+ if device_is_bridge_attached ${parent}; then
+ bridge=$(device_get_bridge ${parent})
+
+ # Detach the parent device.
+ bridge_detach_device ${bridge} ${parent}
+ fi
+
+ # Actually create the device.
+ cmd_quiet ip link add link ${parent} name ${device} address ${address} \
+ type macvlan
+ local ret=$?
+
+ if [ ${ret} -eq ${EXIT_OK} ]; then
+ log DEBUG "macvlan device '${device}' has been created"
+ else
+ log ERROR "Could not create macvlan device '${device}': ${ret}"
+ fi
+
+ # Re-attach device.
+ if isset bridge; then
+ bridge_attach_device ${bridge} ${parent}
+ fi
+
+ return ${ret}
+}
+
+function macvlan_remove() {
+ local device=${1}
+ assert isset device
+
+ device_delete ${device}
+}
--- /dev/null
+#!/bin/bash
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# Copyright (C) 2010 Michael Tremer & Christian Schmidt #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+#
+# XXX This hook is rather unusable because the parent device cannot be used
+# anymore in a bridge.
+#
+
+. /usr/lib/network/header-port
+
+HOOK_SETTINGS="HOOK ADDRESS PARENT"
+
+function _check() {
+ assert isset PARENT
+ assert ismac ADDRESS
+}
+
+function _create() {
+ while [ $# -gt 0 ]; do
+ case "${1}" in
+ --parent-device=*)
+ PARENT=$(cli_get_val ${1})
+ ;;
+ --address=*)
+ ADDRESS=$(cli_get_val ${1})
+ ;;
+ *)
+ warning "Unknown argument '${1}'"
+ ;;
+ esac
+ shift
+ done
+
+ local port=$(port_find_free "${PARENT}${MACVLAN_PORT_INTERFIX}N")
+ assert isset port
+
+ if config_write $(port_file ${port}) ${HOOK_SETTINGS}; then
+ log INFO "New macvlan port '${port}' has been created."
+ fi
+
+ exit ${EXIT_OK}
+}
+
+function _edit() {
+ local port=${1}
+ assert isset port
+ shift
+
+ config_read $(port_file ${port})
+
+ while [ $# -gt 0 ]; do
+ case "${1}" in
+ --address=*)
+ ADDRESS=$(cli_get_val ${1})
+ ;;
+ *)
+ warning "Unknown argument '${1}'"
+ ;;
+ esac
+ shift
+ done
+
+ config_write $(port_file ${port}) ${HOOK_SETTINGS}
+
+ exit ${EXIT_OK}
+}
+
+function _up() {
+ local port=${1}
+ assert isset port
+
+ config_read $(port_file ${port})
+
+ # Create device if not already exists.
+ if ! device_exists ${port}; then
+ macvlan_create "${port}" "${PARENT}" "${ADDRESS}"
+ fi
+
+ exit ${EXIT_OK}
+}
+
+function _down() {
+ local port=${1}
+
+ assert isset port
+
+ config_read $(port_file ${port})
+
+ if ! device_exists ${port}; then
+ exit ${EXIT_OK}
+ fi
+
+ macvlan_remove ${port}
+
+ exit ${EXIT_OK}
+}