Skip to content

Instantly share code, notes, and snippets.

@cloudnull
Last active April 26, 2025 20:21
Show Gist options
  • Save cloudnull/3294dae9dd3fbd6d2b1d29ccbb8d59de to your computer and use it in GitHub Desktop.
Save cloudnull/3294dae9dd3fbd6d2b1d29ccbb8d59de to your computer and use it in GitHub Desktop.

Revisions

  1. Kevin Carter revised this gist Dec 7, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -101,7 +101,7 @@ function setup_host {
    # as set in cloudinit. If, for some reason, cloud-init is not
    # available a random number will be used. This value is hashed and
    # converted to an integer. The return integer is the modulo of "16776216"
    # which is 1000 less than the maximum number of vxlan id's available.
    # which is "1000" less than the maximum number of vxlan id's available.
    VLAN_ID=$(python <<EOC
    import requests
    import hashlib
    @@ -247,4 +247,4 @@ case ${DISTRO_ID} in
    esac

    # Run network setup
    eval "${NETWORK_SETUP_SCRIPT}"
    eval "${NETWORK_SETUP_SCRIPT}"
  2. Kevin Carter revised this gist Dec 5, 2016. 1 changed file with 6 additions and 3 deletions.
    9 changes: 6 additions & 3 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -134,10 +134,13 @@ VLAN_ID="\${VLAN_ID:-${VLAN_ID}}"
    PRIMARY_INTERFACE="\${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"
    # Compute the GROUP membership address. This address is used to to isolate the network broadcast.
    MULTI_OCT="$(( ${VLAN_ID} % 254 ))"
    read -n 3 FRN_OCT <<< \${VLAN_ID}
    FRN_OCT=\$(( \${FRN_OCT} % 254 ))
    MID_OCT="\$(( \${VLAN_ID} % 254 ))"
    END_OCT="\$(( \${VLAN_ID:\${#VLAN_ID}<3?0:-3} % 254 ))"
    # The multi-cast group will be unique to the user. This provides the isolation needed between users.
    GROUP_ADDR="\${GROUP_ADDR:-230.$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 ))}"
    GROUP_ADDR="\${GROUP_ADDR:-230.\$FRN_OCT.\$MID_OCT.\$END_OCT}"
    EOF

    cat > /opt/network-mesh/scripts/00-bond-mtu <<EOF
    @@ -235,7 +238,7 @@ fi
    # Run OS persistence
    case ${DISTRO_ID} in
    centos|rhel)
    echo -e "\n${NETWORK_SETUP_SCRIPT}\n" >> /etc/sysconfig/network-scripts/ifup-post
    sed -i "/exit\s0/i ${NETWORK_SETUP_SCRIPT}\n" /etc/sysconfig/network-scripts/ifup-post
    ;;
    ubuntu|debian)
    ln -sf ${NETWORK_SETUP_SCRIPT} /etc/network/if-up.d/mesh-network
  3. Kevin Carter revised this gist Dec 5, 2016. 1 changed file with 181 additions and 91 deletions.
    272 changes: 181 additions & 91 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -18,116 +18,91 @@
    set -eouv


    function get_ip {
    # This function ensures that a given IP address is available.
    # Should an IP address not be available it will retry until it
    # discovers one.
    set +e
    RETURN_IP=false
    while [ ${RETURN_IP} = false ]; do
    proposed_addr=$1.$(( ( RANDOM % 254 ) + 1 ))
    if ! ping -c 1 -w 1 "${proposed_addr}" 2>&1 > /dev/null; then
    RETURN_IP="${proposed_addr}"
    fi
    done
    set -e
    echo "${proposed_addr}"
    }


    function vxlan_mesh_create {
    function _vxlan_mesh_create {
    # Define our variables
    DEV_NAME="$1"
    DEV_NAME="vxlan-$1"
    PAD_OCTET="$2"
    VID="$3"
    VGID="$4"
    PIF="$5"

    # Remove interface if found
    (ip l | awk "/vxlan-${PAD_OCTET}/ || /br-${DEV_NAME}/ {print \$2}" | sed 's|:||g' | xargs -n 1 ip link del) || true

    # Compute the VXLAN ID
    VXLAN_ID="$(( ${PAD_OCTET} + ${VID} ))"

    # Set the bridge address
    IP_ADDR=$(get_ip 172.16.${PAD_OCTET})
    # Cleanup the interface if found
    (ip link del "$(ip -o l | awk '{print $2}' | grep -wo "^${DEV_NAME}")") || true

    # Create the tunnel interface
    ip link add vxlan-${PAD_OCTET} type vxlan id ${VXLAN_ID} group ${VGID} ttl 4 dev ${PIF}
    ip link add ${DEV_NAME} type vxlan id ${VXLAN_ID} group ${VGID} ttl 4 dev ${PIF}

    # Enable arp notify on the interface and set it up
    sysctl -w net.ipv4.conf.vxlan-${PAD_OCTET}.arp_notify=1
    ip link set vxlan-${PAD_OCTET} up || true
    sysctl -w net.ipv4.conf.${DEV_NAME}.arp_notify=1
    sysctl -w net.ipv6.conf.${DEV_NAME}.disable_ipv6=1
    ip link set ${DEV_NAME} up || true
    }


    function _bridge_create {
    # Define our variables
    DEV_NAME="br-$1"
    PAD_OCTET="$2"
    IP_ADDR="$3"
    BRIDGE_INTERFACE="$4"

    # Cleanup the interface if found
    (ip link del "$(ip -o l | awk '{print $2}' | grep -wo "^${DEV_NAME}")") || true

    # Create a bridge and add the tunnel interface to it
    brctl addbr br-${DEV_NAME}
    brctl stp br-${DEV_NAME} off
    brctl addif br-${DEV_NAME} vxlan-${PAD_OCTET}
    brctl addbr ${DEV_NAME}
    brctl stp ${DEV_NAME} off
    brctl addif ${DEV_NAME} ${BRIDGE_INTERFACE}

    # IP the bridge, enable ARP notify, and set it up
    ip address add ${IP_ADDR}/22 dev br-${DEV_NAME}
    sysctl -w net.ipv4.conf.br-${DEV_NAME}.arp_notify=1
    ip link set br-${DEV_NAME} up
    ip address add ${IP_ADDR}/22 dev ${DEV_NAME}
    sysctl -w net.ipv4.conf.${DEV_NAME}.arp_notify=1
    sysctl -w net.ipv6.conf.${DEV_NAME}.disable_ipv6=1
    ip link set ${DEV_NAME} up

    # Rebroadcast the mac address
    BRIDGE_MAC=$(cat /sys/class/net/br-${DEV_NAME}/address)
    ip link set br-${DEV_NAME} address "${BRIDGE_MAC}"

    # Build out an interface to make the setup persistent.
    cat > /etc/network/mesh-interfaces.d/${DEV_NAME}.cfg <<EOF
    # Build the bridge
    auto br-${DEV_NAME}
    iface br-${DEV_NAME} inet static
    address ${IP_ADDR}/22
    bridge_ports vxlan-${PAD_OCTET}
    bridge_stp off
    pre-up ip link add vxlan-${PAD_OCTET} type vxlan id ${VXLAN_ID} group ${VGID} ttl 4 dev ${PIF}
    up sysctl -w net.ipv4.conf.vxlan-${PAD_OCTET}.arp_notify=1
    up sysctl -w net.ipv4.conf.br-${DEV_NAME}.arp_notify=1
    post-up ip link set br-${DEV_NAME} address ${BRIDGE_MAC}
    post-up ip link set vxlan-${PAD_OCTET} up || true
    down ip link set vxlan-${PAD_OCTET} down || true
    post-down ip link del vxlan-${PAD_OCTET}
    EOF
    BRIDGE_MAC="${BRIDGE_MAC:-$(cat /sys/class/net/${DEV_NAME}/address)}"
    ip link set ${DEV_NAME} address "${BRIDGE_MAC}"
    }


    # This package needs to be installed before bridging will work.
    apt-get update && apt-get install -y bridge-utils python-requests python

    # Ensure the bonds slaves are using an MTU of 9000
    for i in $(cat /sys/class/net/bond0/bonding/slaves); do
    ip link set $i mtu 9000
    if ! grep -q -A3 "iface\s$i\sinet" /etc/network/interfaces | grep "mtu 9000"; then
    sed -i "/iface\s$i\sinet/a mtu 9000" /etc/network/interfaces
    fi
    done

    # Ensure bond0 is using an MTU of 9000
    ip link set bond0 mtu 9000
    if ! grep -q -A3 "iface\sbond0\sinet" /etc/network/interfaces | grep "mtu 9000"; then
    sed -i '/iface\sbond0\sinet/a mtu 9000' /etc/network/interfaces
    fi

    # Create the mesh interfaces directory
    mkdir -p /etc/network/mesh-interfaces.d
    if ! grep -w '^source /etc/network/mesh-interfaces.d' /etc/network/interfaces; then
    echo -e '\nsource /etc/network/mesh-interfaces.d/*.cfg\n' | tee -a /etc/network/interfaces
    fi
    function _run_network_setup {
    if [[ ! -f "/var/run/mesh-active" ]]; then
    for script in $(ls /opt/network-mesh/scripts/*); do
    [ -f "$script" ] && [ -x "$script" ] && "$script"
    done
    touch /var/run/mesh-active
    fi
    }

    # Define the primary network interface. This is determined by the Gateway interface
    # should it not be defined elsewhere. In many cases this interface should NOT be
    # the gateway device. If you're building this in an environment like the Rackspace
    # Public cloud you likley want this to be the internal network interface on SNET or
    # a tenant specific network.
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    # The VLAN ID is derived from the openssh-key provided to the instances
    # as set in cloudinit. If, for some reason, cloud-init is not
    # available a random number will be used. This value is hashed and
    # converted to an integer. The return integer is the modulo of "16776216"
    # which is 1000 less than the maximum number of vxlan id's available.
    VLAN_ID=$(python <<EOC
    function setup_host {
    # If something already exists which overlaps with the network config
    # this next line will remove it.
    (ip -o link | grep -v control | egrep '(vxlan-|br-)' | awk '{print $2}' | sed 's|:||g' | xargs -n 1 ip link del) || true

    # Create the network mesh path
    mkdir -p /opt/network-mesh/scripts

    # This package needs to be installed before bridging will work.
    case ${DISTRO_ID} in
    centos|rhel)
    yum install -y bridge-utils python2 python-requests
    ;;
    ubuntu|debian)
    apt-get update && apt-get install -y bridge-utils python python-requests
    ;;
    esac

    # The VLAN ID is derived from the openssh-key provided to the instances
    # as set in cloudinit. If, for some reason, cloud-init is not
    # available a random number will be used. This value is hashed and
    # converted to an integer. The return integer is the modulo of "16776216"
    # which is 1000 less than the maximum number of vxlan id's available.
    VLAN_ID=$(python <<EOC
    import requests
    import hashlib
    import random
    @@ -143,15 +118,130 @@ finally:
    EOC
    )

    cat > /opt/network-mesh/defaults <<EOF
    # The VLAN ID is derived from the openssh-key provided to the instances
    # as set in cloudinit. If, for some reason, cloud-init is not
    # available a random number will be used. This value is hashed and
    # converted to an integer. The return integer is the modulo of "16776216"
    # which is 1000 less than the maximum number of vxlan id's available.
    VLAN_ID="\${VLAN_ID:-${VLAN_ID}}"
    # Define the primary network interface. This is determined by the Gateway interface
    # should it not be defined elsewhere. In many cases this interface should NOT be
    # the gateway device. If you're building this in an environment like the Rackspace
    # Public cloud you likley want this to be the internal network interface on SNET or
    # a tenant specific network.
    PRIMARY_INTERFACE="\${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"
    # Compute the GROUP membership address. This address is used to to isolate the network broadcast.
    MULTI_OCT="$(( ${VLAN_ID} % 254 ))"
    # The multi-cast group will be unique to the user. This provides the isolation needed between users.
    GROUP_ADDR="${GROUP_ADDR:-230.${MULTI_OCT}.${MULTI_OCT}.${MULTI_OCT}}"
    GROUP_ADDR="\${GROUP_ADDR:-230.$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 ))}"
    EOF

    cat > /opt/network-mesh/scripts/00-bond-mtu <<EOF
    if [[ -d "/sys/class/net/bond0" ]];then
    # Ensure the bonds slaves are using an MTU of 9000
    for i in $(cat /sys/class/net/bond0/bonding/slaves); do
    ip link set \$i mtu 9000
    done
    # Ensure bond0 is using an MTU of 9000
    ip link set bond0 mtu 9000
    fi
    EOF
    chmod +x /opt/network-mesh/scripts/00-bond-mtu

    # Generate functions script
    FUNCTIONS_SCRIPT="/opt/network-mesh/functions"
    echo '#!/usr/bin/env bash' > ${FUNCTIONS_SCRIPT}
    for i in "_vxlan_mesh_create" "_bridge_create" "_run_network_setup"; do
    echo "function $(declare -f $i)" >> ${FUNCTIONS_SCRIPT}
    done

    touch /opt/network-mesh/setup-complete
    }


    function get_ip {
    # This function ensures that a given IP address is available.
    # Should an IP address not be available it will retry until it
    # discovers one.
    set +e
    RETURN_IP=false
    proposed_addr="$1.$(ip -o r g 1 | awk '{print $7}' | awk -F'.' '{print $4}')"
    while [ ${RETURN_IP} = false ]; do
    if ! ping -c 1 -w 1 "${proposed_addr}" 2>&1 > /dev/null; then
    RETURN_IP="${proposed_addr}"
    else
    proposed_addr="$1.$(( ( RANDOM % 254 ) + 1 ))"
    fi
    done
    set -e
    echo "${proposed_addr}"
    }


    # Do basic OS detection
    source /etc/os-release
    export DISTRO_ID="${ID}"
    export DISTRO_NAME="${NAME}"
    export DISTRO_VERSION_ID="${VERSION_ID}"

    # Run basic host setup. This is only run once.
    if [[ ! -f "/opt/network-mesh/setup-complete" ]]; then
    setup_host
    fi

    # Run the network generation setup
    PAD_OCTET=0
    for i in {1..10}; do
    INTERFACE_SCRIPT="/opt/network-mesh/scripts/10-vxlan-$i"
    PAD_OCTET="$(( PAD_OCTET + 4 ))"
    if [[ ! -f "${INTERFACE_SCRIPT}" ]]; then
    echo '#!/usr/bin/env bash' > ${INTERFACE_SCRIPT}
    echo '. /opt/network-mesh/defaults' >> ${INTERFACE_SCRIPT}
    echo '. /opt/network-mesh/functions' >> ${INTERFACE_SCRIPT}
    echo "_vxlan_mesh_create \"$i\" \"${PAD_OCTET}\" \"\${VLAN_ID}\" \"\${GROUP_ADDR}\" \"\${PRIMARY_INTERFACE}\"" >> ${INTERFACE_SCRIPT}
    chmod +x ${INTERFACE_SCRIPT}
    fi
    done

    # Run the network scrip
    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage" "repl"; do
    COUNT="$(( COUNT + 4 ))"
    vxlan_mesh_create "$i" "${COUNT}" "${VLAN_ID}" "${GROUP_ADDR}" "${PRIMARY_INTERFACE}"
    PAD_OCTET=0
    for i in "mgmt" "storage" "repl" "flat" "vlan" "tunnel"; do
    PAD_OCTET="$(( PAD_OCTET + 4 ))"
    let COUNT=COUNT+1
    INTERFACE_SCRIPT="/opt/network-mesh/scripts/20-br-$i"
    if [[ ! -f "${INTERFACE_SCRIPT}" ]]; then
    IP_ADDR="$(get_ip 172.16.${PAD_OCTET})"
    echo '#!/usr/bin/env bash' > ${INTERFACE_SCRIPT}
    echo '. /opt/network-mesh/defaults' >> ${INTERFACE_SCRIPT}
    echo '. /opt/network-mesh/functions' >> ${INTERFACE_SCRIPT}
    echo "_bridge_create \"$i\" \"${PAD_OCTET}\" \"${IP_ADDR}\" \"vxlan-${COUNT}\"" >> ${INTERFACE_SCRIPT}
    chmod +x ${INTERFACE_SCRIPT}
    fi
    done

    NETWORK_SETUP_SCRIPT="/opt/network-mesh/run_network_setup.sh"
    if [[ ! -f "${NETWORK_SETUP_SCRIPT}" ]]; then
    echo '#!/bin/bash' > "${NETWORK_SETUP_SCRIPT}"
    echo ". /opt/network-mesh/functions" >> "${NETWORK_SETUP_SCRIPT}"
    echo "_run_network_setup" >> "${NETWORK_SETUP_SCRIPT}"
    chmod +x "${NETWORK_SETUP_SCRIPT}"
    fi

    # Run OS persistence
    case ${DISTRO_ID} in
    centos|rhel)
    echo -e "\n${NETWORK_SETUP_SCRIPT}\n" >> /etc/sysconfig/network-scripts/ifup-post
    ;;
    ubuntu|debian)
    ln -sf ${NETWORK_SETUP_SCRIPT} /etc/network/if-up.d/mesh-network
    chmod +x /etc/network/if-up.d/mesh-network
    ;;
    esac

    # Run network setup
    eval "${NETWORK_SETUP_SCRIPT}"
  4. Kevin Carter revised this gist Dec 3, 2016. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -30,8 +30,8 @@ function get_ip {
    RETURN_IP="${proposed_addr}"
    fi
    done
    echo "${proposed_addr}"
    set -e
    echo "${proposed_addr}"
    }


    @@ -149,6 +149,7 @@ MULTI_OCT="$(( ${VLAN_ID} % 254 ))"
    # The multi-cast group will be unique to the user. This provides the isolation needed between users.
    GROUP_ADDR="${GROUP_ADDR:-230.${MULTI_OCT}.${MULTI_OCT}.${MULTI_OCT}}"

    # Run the network scrip
    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage" "repl"; do
    COUNT="$(( COUNT + 4 ))"
  5. Kevin Carter revised this gist Dec 3, 2016. 1 changed file with 11 additions and 3 deletions.
    14 changes: 11 additions & 3 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -19,12 +19,18 @@ set -eouv


    function get_ip {
    set +e
    # This function ensures that a given IP address is available.
    # Should an IP address not be available it will retry until it
    # discovers one.
    proposed_addr=$1.$(( ( RANDOM % 254 ) + 1 ))
    ping -c 1 -w 1 ${proposed_addr} 2>&1 > /dev/null && get_ip $1 || echo "${proposed_addr}"
    set +e
    RETURN_IP=false
    while [ ${RETURN_IP} = false ]; do
    proposed_addr=$1.$(( ( RANDOM % 254 ) + 1 ))
    if ! ping -c 1 -w 1 "${proposed_addr}" 2>&1 > /dev/null; then
    RETURN_IP="${proposed_addr}"
    fi
    done
    echo "${proposed_addr}"
    set -e
    }

    @@ -139,6 +145,8 @@ EOC

    # Compute the GROUP membership address. This address is used to to isolate the network broadcast.
    MULTI_OCT="$(( ${VLAN_ID} % 254 ))"

    # The multi-cast group will be unique to the user. This provides the isolation needed between users.
    GROUP_ADDR="${GROUP_ADDR:-230.${MULTI_OCT}.${MULTI_OCT}.${MULTI_OCT}}"

    COUNT=0
  6. Kevin Carter revised this gist Dec 3, 2016. 1 changed file with 26 additions and 21 deletions.
    47 changes: 26 additions & 21 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -19,11 +19,13 @@ set -eouv


    function get_ip {
    set +e
    # This function ensures that a given IP address is available.
    # Should an IP address not be available it will retry until it
    # discovers one.
    proposed_addr=$1.$(( ( RANDOM % 254 ) + 1 ))
    ping -c 1 -w 1 ${proposed_addr} 2>&1 > /dev/null && get_ip $1 || echo "${proposed_addr}"
    set -e
    }


    @@ -35,23 +37,26 @@ function vxlan_mesh_create {
    VGID="$4"
    PIF="$5"

    # Compute the VXLAN ID
    # Remove interface if found
    (ip l | awk "/vxlan-${PAD_OCTET}/ || /br-${DEV_NAME}/ {print \$2}" | sed 's|:||g' | xargs -n 1 ip link del) || true

    # Compute the VXLAN ID
    VXLAN_ID="$(( ${PAD_OCTET} + ${VID} ))"

    # Set the bridge address
    IP_ADDR=$(get_ip 172.16.${PAD_OCTET}})
    IP_ADDR=$(get_ip 172.16.${PAD_OCTET})

    # Create the tunnel interface
    ip link add ${DEV_NAME}-mesh type vxlan id ${VXLAN_ID} group ${VGID} ttl 4 dev ${PIF}
    ip link add vxlan-${PAD_OCTET} type vxlan id ${VXLAN_ID} group ${VGID} ttl 4 dev ${PIF}

    # Enable arp notify on the interface and set it up
    sysctl -w net.ipv4.conf.${DEV_NAME}-mesh.arp_notify=1
    ip link set ${DEV_NAME}-mesh up || true
    sysctl -w net.ipv4.conf.vxlan-${PAD_OCTET}.arp_notify=1
    ip link set vxlan-${PAD_OCTET} up || true

    # Create a bridge and add the tunnel interface to it
    brctl addbr br-${DEV_NAME}
    brctl stp br-${DEV_NAME} off
    brctl addif br-${DEV_NAME} ${DEV_NAME}-mesh
    brctl addif br-${DEV_NAME} vxlan-${PAD_OCTET}

    # IP the bridge, enable ARP notify, and set it up
    ip address add ${IP_ADDR}/22 dev br-${DEV_NAME}
    @@ -68,15 +73,15 @@ function vxlan_mesh_create {
    auto br-${DEV_NAME}
    iface br-${DEV_NAME} inet static
    address ${IP_ADDR}/22
    bridge_ports ${DEV_NAME}-mesh
    bridge_ports vxlan-${PAD_OCTET}
    bridge_stp off
    pre-up ip link add ${DEV_NAME}-mesh type vxlan id ${VXLAN_ID} group ${VGID} ttl 4 dev ${PIF}
    up sysctl -w net.ipv4.conf.${DEV_NAME}-mesh.arp_notify=1
    pre-up ip link add vxlan-${PAD_OCTET} type vxlan id ${VXLAN_ID} group ${VGID} ttl 4 dev ${PIF}
    up sysctl -w net.ipv4.conf.vxlan-${PAD_OCTET}.arp_notify=1
    up sysctl -w net.ipv4.conf.br-${DEV_NAME}.arp_notify=1
    post-up ip link set br-${DEV_NAME} address ${BRIDGE_MAC}
    post-up ip link set ${DEV_NAME}-mesh up || true
    down ip link set ${DEV_NAME}-mesh down || true
    post-down ip link del ${DEV_NAME}-mesh
    post-up ip link set vxlan-${PAD_OCTET} up || true
    down ip link set vxlan-${PAD_OCTET} down || true
    post-down ip link del vxlan-${PAD_OCTET}
    EOF
    }

    @@ -104,6 +109,13 @@ if ! grep -w '^source /etc/network/mesh-interfaces.d' /etc/network/interfaces; t
    echo -e '\nsource /etc/network/mesh-interfaces.d/*.cfg\n' | tee -a /etc/network/interfaces
    fi

    # Define the primary network interface. This is determined by the Gateway interface
    # should it not be defined elsewhere. In many cases this interface should NOT be
    # the gateway device. If you're building this in an environment like the Rackspace
    # Public cloud you likley want this to be the internal network interface on SNET or
    # a tenant specific network.
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    # The VLAN ID is derived from the openssh-key provided to the instances
    # as set in cloudinit. If, for some reason, cloud-init is not
    # available a random number will be used. This value is hashed and
    @@ -125,19 +137,12 @@ finally:
    EOC
    )

    # Define the primary network interface. This is determined by the Gateway interface
    # should it not be defined elsewhere. In many cases this interface should NOT be
    # the gateway device. If you're building this in an environment like the Rackspace
    # Public cloud you likley want this to be the internal network interface on SNET or
    # a tenant specific network.
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    # Compute the GROUP membership address. This address is used to to isolate the network broadcast.
    MULTI_OCT="$(( ${VLAN_ID} % 254 ))"
    GROUP_ADDR="${GROUP_ADDR:-230.${MULTI_OCT}.${MULTI_OCT}.${MULTI_OCT}"
    GROUP_ADDR="${GROUP_ADDR:-230.${MULTI_OCT}.${MULTI_OCT}.${MULTI_OCT}}"

    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage" "repl"; do
    COUNT=$(( COUNT + 4 ))
    COUNT="$(( COUNT + 4 ))"
    vxlan_mesh_create "$i" "${COUNT}" "${VLAN_ID}" "${GROUP_ADDR}" "${PRIMARY_INTERFACE}"
    done
  7. Kevin Carter revised this gist Dec 3, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -88,7 +88,7 @@ apt-get update && apt-get install -y bridge-utils python-requests python
    for i in $(cat /sys/class/net/bond0/bonding/slaves); do
    ip link set $i mtu 9000
    if ! grep -q -A3 "iface\s$i\sinet" /etc/network/interfaces | grep "mtu 9000"; then
    sed -i "/iface\s$1\sinet/a mtu 9000" /etc/network/interfaces
    sed -i "/iface\s$i\sinet/a mtu 9000" /etc/network/interfaces
    fi
    done

  8. Kevin Carter revised this gist Dec 3, 2016. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -133,10 +133,11 @@ EOC
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    # Compute the GROUP membership address. This address is used to to isolate the network broadcast.
    GROUP_ADDR="230.$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 ))"
    MULTI_OCT="$(( ${VLAN_ID} % 254 ))"
    GROUP_ADDR="${GROUP_ADDR:-230.${MULTI_OCT}.${MULTI_OCT}.${MULTI_OCT}"
    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage" "repl"; do
    COUNT=$(( COUNT + 4 ))
    vxlan_mesh_create $i ${COUNT} ${VLAN_ID} ${GROUP_ADDR} ${PRIMARY_INTERFACE}
    vxlan_mesh_create "$i" "${COUNT}" "${VLAN_ID}" "${GROUP_ADDR}" "${PRIMARY_INTERFACE}"
    done
  9. Kevin Carter revised this gist Dec 3, 2016. 1 changed file with 6 additions and 4 deletions.
    10 changes: 6 additions & 4 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -112,11 +112,13 @@ fi
    VLAN_ID=$(python <<EOC
    import requests
    import hashlib
    import random
    try:
    key = requests.get('http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key')
    string = key.encode('utf-8')
    except Exception:
    string = '$(( ( RANDOM ) ))'
    string = str(random.randrange(1, 16776216))
    else:
    string = key.content.encode('utf-8')
    finally:
    string = hashlib.sha256(string).hexdigest()
    print(int(string, 36) % 16776216)
    @@ -130,8 +132,8 @@ EOC
    # a tenant specific network.
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    # Compute the GROUP membership address
    GROUP_ADDR="239.$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 ))"
    # Compute the GROUP membership address. This address is used to to isolate the network broadcast.
    GROUP_ADDR="230.$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 ))"

    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage" "repl"; do
  10. Kevin Carter revised this gist Dec 3, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -131,7 +131,7 @@ EOC
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    # Compute the GROUP membership address
    GROUP_ADDR="239.$(( ( RANDOM % 254 ) )).$(( ( RANDOM % 254 ) )).$(( ${VLAN_ID} % 254 ))"
    GROUP_ADDR="239.$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 )).$(( ${VLAN_ID} % 254 ))"

    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage" "repl"; do
  11. Kevin Carter revised this gist Dec 2, 2016. 1 changed file with 21 additions and 14 deletions.
    35 changes: 21 additions & 14 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -17,15 +17,6 @@

    set -eouv

    # This package needs to be installed before bridging will work.
    apt-get update && apt-get install -y bridge-utils python-requests python

    # Define the primary network interface. This is determined by the Gateway interface
    # should it not be defined elsewhere. In many cases this interface should NOT be
    # the gateway device. If you're building this in an environment like the Rackspace
    # Public cloud you likley want this to be the internal network interface on SNET or
    # a tenant specific network.
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    function get_ip {
    # This function ensures that a given IP address is available.
    @@ -35,21 +26,23 @@ function get_ip {
    ping -c 1 -w 1 ${proposed_addr} 2>&1 > /dev/null && get_ip $1 || echo "${proposed_addr}"
    }


    function vxlan_mesh_create {
    # Define our variables
    DEV_NAME="$1"
    PAD_OCTET="$2"
    VID="$3"
    VGID="$4"
    PIF="$5"

    # Compute the VXLAN ID and GROUP membership
    GROUP_ADDR="239.$(( ( RANDOM % 254 ) )).$(( ( RANDOM % 254 ) )).$(( ${VID} % 254 ))"
    # Compute the VXLAN ID
    VXLAN_ID="$(( ${PAD_OCTET} + ${VID} ))"

    # Set the bridge address
    IP_ADDR=$(get_ip 172.16.${PAD_OCTET}})

    # Create the tunnel interface
    ip link add ${DEV_NAME}-mesh type vxlan id ${VXLAN_ID} group ${GROUP_ADDR} ttl 4 dev ${PRIMARY_INTERFACE}
    ip link add ${DEV_NAME}-mesh type vxlan id ${VXLAN_ID} group ${VGID} ttl 4 dev ${PIF}

    # Enable arp notify on the interface and set it up
    sysctl -w net.ipv4.conf.${DEV_NAME}-mesh.arp_notify=1
    @@ -77,7 +70,7 @@ iface br-${DEV_NAME} inet static
    address ${IP_ADDR}/22
    bridge_ports ${DEV_NAME}-mesh
    bridge_stp off
    pre-up ip link add ${DEV_NAME}-mesh type vxlan id ${VXLAN_ID} group ${GROUP_ADDR} ttl 4 dev ${PRIMARY_INTERFACE}
    pre-up ip link add ${DEV_NAME}-mesh type vxlan id ${VXLAN_ID} group ${VGID} ttl 4 dev ${PIF}
    up sysctl -w net.ipv4.conf.${DEV_NAME}-mesh.arp_notify=1
    up sysctl -w net.ipv4.conf.br-${DEV_NAME}.arp_notify=1
    post-up ip link set br-${DEV_NAME} address ${BRIDGE_MAC}
    @@ -87,6 +80,10 @@ iface br-${DEV_NAME} inet static
    EOF
    }


    # This package needs to be installed before bridging will work.
    apt-get update && apt-get install -y bridge-utils python-requests python

    # Ensure the bonds slaves are using an MTU of 9000
    for i in $(cat /sys/class/net/bond0/bonding/slaves); do
    ip link set $i mtu 9000
    @@ -126,8 +123,18 @@ finally:
    EOC
    )

    # Define the primary network interface. This is determined by the Gateway interface
    # should it not be defined elsewhere. In many cases this interface should NOT be
    # the gateway device. If you're building this in an environment like the Rackspace
    # Public cloud you likley want this to be the internal network interface on SNET or
    # a tenant specific network.
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    # Compute the GROUP membership address
    GROUP_ADDR="239.$(( ( RANDOM % 254 ) )).$(( ( RANDOM % 254 ) )).$(( ${VLAN_ID} % 254 ))"

    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage" "repl"; do
    COUNT=$(( COUNT + 4 ))
    vxlan_mesh_create $i $COUNT $VLAN_ID
    vxlan_mesh_create $i ${COUNT} ${VLAN_ID} ${GROUP_ADDR} ${PRIMARY_INTERFACE}
    done
  12. Kevin Carter revised this gist Dec 2, 2016. 1 changed file with 10 additions and 5 deletions.
    15 changes: 10 additions & 5 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -87,14 +87,19 @@ iface br-${DEV_NAME} inet static
    EOF
    }

    # Ensure the bonds are using an MTU of 9000
    # Ensure the bonds slaves are using an MTU of 9000
    for i in $(cat /sys/class/net/bond0/bonding/slaves); do
    ip link set $i mtu 9000
    if ! grep -q -A3 "iface\s$i\sinet" /etc/network/interfaces | grep "mtu 9000"; then
    sed -i "/iface\s$1\sinet/a mtu 9000" /etc/network/interfaces
    fi
    done
    ip link set bond0 mtu 9000

    # Made the mtu setting persistent
    sed -i '/iface\sbond0\sinet/a mtu 9000' /etc/network/interfaces
    # Ensure bond0 is using an MTU of 9000
    ip link set bond0 mtu 9000
    if ! grep -q -A3 "iface\sbond0\sinet" /etc/network/interfaces | grep "mtu 9000"; then
    sed -i '/iface\sbond0\sinet/a mtu 9000' /etc/network/interfaces
    fi

    # Create the mesh interfaces directory
    mkdir -p /etc/network/mesh-interfaces.d
    @@ -103,7 +108,7 @@ if ! grep -w '^source /etc/network/mesh-interfaces.d' /etc/network/interfaces; t
    fi

    # The VLAN ID is derived from the openssh-key provided to the instances
    # as set defined in cloudinit. If for some reason cloud-init is not
    # as set in cloudinit. If, for some reason, cloud-init is not
    # available a random number will be used. This value is hashed and
    # converted to an integer. The return integer is the modulo of "16776216"
    # which is 1000 less than the maximum number of vxlan id's available.
  13. Kevin Carter revised this gist Dec 2, 2016. No changes.
  14. Kevin Carter revised this gist Dec 2, 2016. No changes.
  15. Kevin Carter revised this gist Dec 2, 2016. 1 changed file with 58 additions and 30 deletions.
    88 changes: 58 additions & 30 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -12,10 +12,13 @@
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    #
    # (c) 2016, Kevin Carter <[email protected]>

    set -eouv

    # This package needs to be installed before bridging will work.
    apt-get update
    apt-get install -y bridge-utils python-requests python
    apt-get update && apt-get install -y bridge-utils python-requests python

    # Define the primary network interface. This is determined by the Gateway interface
    # should it not be defined elsewhere. In many cases this interface should NOT be
    @@ -25,76 +28,101 @@ apt-get install -y bridge-utils python-requests python
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    function get_ip {
    # This function ensures that a given IP address is available.
    # Should an IP address not be available it will retry until it
    # discovers one.
    proposed_addr=$1.$(( ( RANDOM % 254 ) + 1 ))
    ping -c 1 -w 1 ${proposed_addr} 2>&1 > /dev/null && get_ip $1 || echo "${proposed_addr}"
    }

    function vxlan_mesh_create {
    # Define our variables
    DEV_NAME="$1"
    PAD_OCTET="$2"
    VID="$3"

    # Compute the VXLAN ID and GROUP membership
    GROUP_ADDR="239.$(( ( RANDOM % 254 ) )).$(( ( RANDOM % 254 ) )).$(( ${VID} % 254 ))"
    VXLAN_ID="$(( ${PAD_OCTET} + ${VID} ))"

    # Set the bridge address
    IP_ADDR=$(get_ip 172.16.${PAD_OCTET}})

    # Create the tunnel interface
    ip link add $1-mesh type vxlan id $(( $2 + $3 )) group 239.51.50.$(( VLAN_ID % 254 )) ttl 4 dev $PRIMARY_INTERFACE
    ip link add ${DEV_NAME}-mesh type vxlan id ${VXLAN_ID} group ${GROUP_ADDR} ttl 4 dev ${PRIMARY_INTERFACE}

    # Enable arp notify on the interface and set it up
    sysctl -w net.ipv4.conf.${DEV_NAME}-mesh.arp_notify=1
    ip link set ${DEV_NAME}-mesh up || true

    ip link set $1-mesh up || true
    sysctl -w net.ipv4.conf.$1-mesh.arp_notify=1
    ip link set $1-mesh up
    # Create a bridge and add the tunnel interface to it
    brctl addbr br-${DEV_NAME}
    brctl stp br-${DEV_NAME} off
    brctl addif br-${DEV_NAME} ${DEV_NAME}-mesh

    brctl addbr br-$1
    brctl stp br-$1 off
    brctl addif br-$1 $1-mesh
    # IP the bridge, enable ARP notify, and set it up
    ip address add ${IP_ADDR}/22 dev br-${DEV_NAME}
    sysctl -w net.ipv4.conf.br-${DEV_NAME}.arp_notify=1
    ip link set br-${DEV_NAME} up

    IP_ADDR=$(get_ip 172.16.$2)
    ip address add ${IP_ADDR}/22 dev br-$1
    sysctl -w net.ipv4.conf.br-$1.arp_notify=1
    ip link set br-$1 up
    BRIDGE_MAC=$(cat /sys/class/net/br-$1/address)
    ip link set br-$1 address "${BRIDGE_MAC}"
    # Rebroadcast the mac address
    BRIDGE_MAC=$(cat /sys/class/net/br-${DEV_NAME}/address)
    ip link set br-${DEV_NAME} address "${BRIDGE_MAC}"

    # Build out the interface.
    cat > /etc/network/mesh-interfaces.d/$1.cfg <<EOF
    # Build out an interface to make the setup persistent.
    cat > /etc/network/mesh-interfaces.d/${DEV_NAME}.cfg <<EOF
    # Build the bridge
    auto br-$1
    iface br-$1 inet static
    auto br-${DEV_NAME}
    iface br-${DEV_NAME} inet static
    address ${IP_ADDR}/22
    bridge_ports $1-mesh
    bridge_ports ${DEV_NAME}-mesh
    bridge_stp off
    pre-up ip link add $1-mesh type vxlan id $(( $2 + $3 )) group 239.51.50.$(( VLAN_ID % 254 )) ttl 4 dev $PRIMARY_INTERFACE
    up sysctl -w net.ipv4.conf.$1-mesh.arp_notify=1
    up sysctl -w net.ipv4.conf.br-$1.arp_notify=1
    post-up ip link set br-$1 address ${BRIDGE_MAC}
    post-up ip link set $1-mesh up || true
    down ip link set $1-mesh down || true
    post-down ip link del $1-mesh
    pre-up ip link add ${DEV_NAME}-mesh type vxlan id ${VXLAN_ID} group ${GROUP_ADDR} ttl 4 dev ${PRIMARY_INTERFACE}
    up sysctl -w net.ipv4.conf.${DEV_NAME}-mesh.arp_notify=1
    up sysctl -w net.ipv4.conf.br-${DEV_NAME}.arp_notify=1
    post-up ip link set br-${DEV_NAME} address ${BRIDGE_MAC}
    post-up ip link set ${DEV_NAME}-mesh up || true
    down ip link set ${DEV_NAME}-mesh down || true
    post-down ip link del ${DEV_NAME}-mesh
    EOF
    }

    # Ensure the bonds are using an MTU of 9000
    for i in $(cat /sys/class/net/bond0/bonding/slaves); do
    ip link set $i mtu 9000
    done

    ip link set bond0 mtu 9000

    # Made the mtu setting persistent
    sed -i '/iface\sbond0\sinet/a mtu 9000' /etc/network/interfaces

    # Create the mesh interfaces directory
    mkdir -p /etc/network/mesh-interfaces.d
    if ! grep -w '^source /etc/network/mesh-interfaces.d' /etc/network/interfaces; then
    echo -e '\nsource /etc/network/mesh-interfaces.d/*.cfg\n' | tee -a /etc/network/interfaces
    fi

    # The VLAN ID is derived from the openssh-key provided to the instances
    # as set defined in cloudinit. If for some reason cloud-init is not
    # available a random number will be used. This value is hashed and
    # converted to an integer. The return integer is the modulo of "16776216"
    # which is 1000 less than the maximum number of vxlan id's available.
    VLAN_ID=$(python <<EOC
    import requests
    import hashlib
    try:
    key = requests.get('http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key')
    string = key.encode('utf-8')
    except Exception:
    string = 'UNKNOWN'
    string = '$(( ( RANDOM ) ))'
    finally:
    string = hashlib.sha256(string).hexdigest()
    print(int(string, 36) % 16776216)
    EOC
    )

    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage"; do
    for i in "mgmt" "vlan" "vxlan" "storage" "repl"; do
    COUNT=$(( COUNT + 4 ))
    vxlan_mesh_create $i $COUNT $VLAN_ID
    done
  16. Kevin Carter revised this gist Dec 1, 2016. 1 changed file with 13 additions and 0 deletions.
    13 changes: 13 additions & 0 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,17 @@
    #!/bin/bash
    # Copyright 2016, Rackspace US, Inc.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    # http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.

    # This package needs to be installed before bridging will work.
    apt-get update
  17. Kevin Carter revised this gist Dec 1, 2016. 1 changed file with 22 additions and 24 deletions.
    46 changes: 22 additions & 24 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -1,21 +1,8 @@
    #!/bin/bash
    # Copyright 2014, Rackspace US, Inc.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    # http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.

    # This package needs to be installed before bridging will work.
    apt-get update
    apt-get install -y bridge-utils
    apt-get install -y bridge-utils python-requests python

    # Define the primary network interface. This is determined by the Gateway interface
    # should it not be defined elsewhere. In many cases this interface should NOT be
    @@ -31,7 +18,7 @@ function get_ip {

    function vxlan_mesh_create {
    # Create the tunnel interface
    ip link add $1-mesh type vxlan id $(( $2 + 5149 )) group 239.51.50.1 ttl 4 dev $PRIMARY_INTERFACE
    ip link add $1-mesh type vxlan id $(( $2 + $3 )) group 239.51.50.$(( VLAN_ID % 254 )) ttl 4 dev $PRIMARY_INTERFACE

    ip link set $1-mesh up || true
    sysctl -w net.ipv4.conf.$1-mesh.arp_notify=1
    @@ -50,22 +37,19 @@ function vxlan_mesh_create {

    # Build out the interface.
    cat > /etc/network/mesh-interfaces.d/$1.cfg <<EOF
    auto $1-mesh
    iface $1-mesh inet manual
    pre-up ip link add $1-mesh type vxlan id $(( $2 + 5149 )) group 239.51.50.1 ttl 4 dev $PRIMARY_INTERFACE
    up sysctl -w net.ipv4.conf.$1-mesh.arp_notify=1
    post-up ip link set $1-mesh up || true
    down ip link set $1-mesh down || true
    post-down ip link del $1-mesh
    # Build the bridge
    auto br-$1
    iface br-$1 inet static
    address ${IP_ADDR}/22
    bridge_ports $1-mesh
    bridge_stp off
    pre-up ip link add $1-mesh type vxlan id $(( $2 + $3 )) group 239.51.50.$(( VLAN_ID % 254 )) ttl 4 dev $PRIMARY_INTERFACE
    up sysctl -w net.ipv4.conf.$1-mesh.arp_notify=1
    up sysctl -w net.ipv4.conf.br-$1.arp_notify=1
    post-up ip link set br-$1 address ${BRIDGE_MAC}
    post-up ip link set $1-mesh up || true
    down ip link set $1-mesh down || true
    post-down ip link del $1-mesh
    EOF
    }

    @@ -82,8 +66,22 @@ if ! grep -w '^source /etc/network/mesh-interfaces.d' /etc/network/interfaces; t
    echo -e '\nsource /etc/network/mesh-interfaces.d/*.cfg\n' | tee -a /etc/network/interfaces
    fi

    VLAN_ID=$(python <<EOC
    import requests
    import hashlib
    try:
    key = requests.get('http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key')
    string = key.encode('utf-8')
    except Exception:
    string = 'UNKNOWN'
    finally:
    string = hashlib.sha256(string).hexdigest()
    print(int(string, 36) % 16776216)
    EOC
    )

    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage"; do
    COUNT=$(( COUNT + 4 ))
    vxlan_mesh_create $i $COUNT
    vxlan_mesh_create $i $COUNT $VLAN_ID
    done
  18. Kevin Carter revised this gist Dec 1, 2016. 1 changed file with 13 additions and 0 deletions.
    13 changes: 13 additions & 0 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,17 @@
    #!/bin/bash
    # Copyright 2014, Rackspace US, Inc.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    # http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.

    # This package needs to be installed before bridging will work.
    apt-get update
  19. Kevin Carter revised this gist Dec 1, 2016. 1 changed file with 33 additions and 12 deletions.
    45 changes: 33 additions & 12 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -12,42 +12,63 @@ apt-get install -y bridge-utils
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    function get_ip {
    # Generate a random IP
    proposed_addr=$1.$(( ( RANDOM % 254 ) + 1 ))
    # See if the IP address is consumed and print if it's not.
    ping -c 1 -w 1 ${proposed_addr} 2>&1 > /dev/null && get_ip $1 || echo "${proposed_addr}"
    }

    function vxlan_mesh_create {
    # Create the tunnel interface.
    # Create the tunnel interface
    ip link add $1-mesh type vxlan id $(( $2 + 5149 )) group 239.51.50.1 ttl 4 dev $PRIMARY_INTERFACE

    # Up the tunnel interface.
    ip link set $1-mesh up || true
    sysctl -w net.ipv4.conf.$1-mesh.arp_notify=1
    ip link set $1-mesh up

    # create the bridge.
    brctl addbr br-$1
    brctl stp br-$1 off
    # Add the tunnel interface to the bridge.
    brctl addif br-$1 $1-mesh

    # Set an IP address on the bridge.
    ip address add $(get_ip 172.16.$2)/24 dev br-$1
    IP_ADDR=$(get_ip 172.16.$2)
    ip address add ${IP_ADDR}/22 dev br-$1
    sysctl -w net.ipv4.conf.br-$1.arp_notify=1
    ip link set br-$1 up
    # Broadcast a notification for the interface on the bridge.
    ip link set br-$1 address "$(cat /sys/class/net/br-$1/address)"
    BRIDGE_MAC=$(cat /sys/class/net/br-$1/address)
    ip link set br-$1 address "${BRIDGE_MAC}"

    # Build out the interface.
    cat > /etc/network/mesh-interfaces.d/$1.cfg <<EOF
    auto $1-mesh
    iface $1-mesh inet manual
    pre-up ip link add $1-mesh type vxlan id $(( $2 + 5149 )) group 239.51.50.1 ttl 4 dev $PRIMARY_INTERFACE
    up sysctl -w net.ipv4.conf.$1-mesh.arp_notify=1
    post-up ip link set $1-mesh up || true
    down ip link set $1-mesh down || true
    post-down ip link del $1-mesh
    # Build the bridge
    auto br-$1
    iface br-$1 inet static
    address ${IP_ADDR}/22
    bridge_ports $1-mesh
    bridge_stp off
    up sysctl -w net.ipv4.conf.br-$1.arp_notify=1
    post-up ip link set br-$1 address ${BRIDGE_MAC}
    EOF
    }

    # Ensure the bonds are using an MTU of 9000
    for i in $(cat /sys/class/net/bond0/bonding/slaves); do
    ip link set $i mtu 9000
    done

    ip link set bond0 mtu 9000

    # Create the mesh. This will create various bridges and space the address
    # subnets out in increments of 4.
    # Create the mesh interfaces directory
    mkdir -p /etc/network/mesh-interfaces.d
    if ! grep -w '^source /etc/network/mesh-interfaces.d' /etc/network/interfaces; then
    echo -e '\nsource /etc/network/mesh-interfaces.d/*.cfg\n' | tee -a /etc/network/interfaces
    fi

    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage"; do
    COUNT=$(( COUNT + 4 ))
  20. Kevin Carter created this gist Dec 1, 2016.
    55 changes: 55 additions & 0 deletions vxlan-mesh-create.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,55 @@
    #!/bin/bash

    # This package needs to be installed before bridging will work.
    apt-get update
    apt-get install -y bridge-utils

    # Define the primary network interface. This is determined by the Gateway interface
    # should it not be defined elsewhere. In many cases this interface should NOT be
    # the gateway device. If you're building this in an environment like the Rackspace
    # Public cloud you likley want this to be the internal network interface on SNET or
    # a tenant specific network.
    PRIMARY_INTERFACE="${PRIMARY_INTERFACE:=$(ip -o r g 1 | awk '{print $5}')}"

    function get_ip {
    # Generate a random IP
    proposed_addr=$1.$(( ( RANDOM % 254 ) + 1 ))
    # See if the IP address is consumed and print if it's not.
    ping -c 1 -w 1 ${proposed_addr} 2>&1 > /dev/null && get_ip $1 || echo "${proposed_addr}"
    }

    function vxlan_mesh_create {
    # Create the tunnel interface.
    ip link add $1-mesh type vxlan id $(( $2 + 5149 )) group 239.51.50.1 ttl 4 dev $PRIMARY_INTERFACE

    # Up the tunnel interface.
    ip link set $1-mesh up || true
    sysctl -w net.ipv4.conf.$1-mesh.arp_notify=1

    # create the bridge.
    brctl addbr br-$1
    brctl stp br-$1 off
    # Add the tunnel interface to the bridge.
    brctl addif br-$1 $1-mesh

    # Set an IP address on the bridge.
    ip address add $(get_ip 172.16.$2)/24 dev br-$1
    sysctl -w net.ipv4.conf.br-$1.arp_notify=1
    ip link set br-$1 up
    # Broadcast a notification for the interface on the bridge.
    ip link set br-$1 address "$(cat /sys/class/net/br-$1/address)"
    }

    # Ensure the bonds are using an MTU of 9000
    for i in $(cat /sys/class/net/bond0/bonding/slaves); do
    ip link set $i mtu 9000
    done
    ip link set bond0 mtu 9000

    # Create the mesh. This will create various bridges and space the address
    # subnets out in increments of 4.
    COUNT=0
    for i in "mgmt" "vlan" "vxlan" "storage"; do
    COUNT=$(( COUNT + 4 ))
    vxlan_mesh_create $i $COUNT
    done