Move bridge-creation code from weave script into Go code

via weaveutil create-bridge function
This commit is contained in:
Bryan Boreham committed 2017-04-17 19:41:47 +00:00
1 parent 6fd9f471ff
commit 8051f51d46
5 files changed
+115 -195

No files matched your search

+17 -2
View File
@@ -28,6 +28,23 @@ const (
Inconsistent
)
// Returns a string that is consistent with the weave script
func (t BridgeType) String() string {
switch t {
case None:
return "none"
case Bridge:
return "bridge"
case Fastdp:
return "fastdp"
case BridgedFastdp:
return "bridged_fastdp"
case Inconsistent:
return "inconsistent"
}
return "unknown"
}
func DetectBridgeType(weaveBridgeName, datapathName string) BridgeType {
bridge, _ := netlink.LinkByName(weaveBridgeName)
datapath, _ := netlink.LinkByName(datapathName)
@@ -151,8 +168,6 @@ func FindBridgeIP(bridgeName string, subnet *net.IPNet) (net.IP, error) {
}
type BridgeConfig struct {
DBPrefix string
HostRoot string
DockerBridgeName string
WeaveBridgeName string
DatapathName string
+45
View File
@@ -0,0 +1,45 @@
package main
import (
"fmt"
"strconv"
weavenet "github.com/weaveworks/weave/net"
)
func detectBridgeType(args []string) error {
if len(args) != 2 {
cmdUsage("detect-bridge-type", "<weave-bridge-name> <datapath-name>")
}
bridgeType := weavenet.DetectBridgeType(args[0], args[1])
fmt.Println(bridgeType.String())
return nil
}
func createBridge(args []string) error {
if len(args) != 8 {
cmdUsage("create-bridge", "<docker-bridge-name> <weave-bridge-name> <datapath-name> <mtu> <port> <mac> <no-fastdp> <no-bridged-fastdp>")
}
mtu, err := strconv.Atoi(args[3])
if err != nil && args[3] != "" {
return err
}
port, err := strconv.Atoi(args[4])
if err != nil {
return err
}
config := weavenet.BridgeConfig{
DockerBridgeName: args[0],
WeaveBridgeName: args[1],
DatapathName: args[2],
MTU: mtu,
Port: port,
Mac: args[5],
NoFastdp: args[6] != "",
NoBridgedFastdp: args[7] != "",
}
bridgeType, err := weavenet.CreateBridge(&config)
fmt.Println(bridgeType.String())
return err
}
-13
View File
@@ -31,19 +31,6 @@ func deleteDatapath(args []string) error {
return odp.DeleteDatapath(args[0])
}
// Checks whether a datapath can be created by actually creating and destroying it
func checkDatapath(args []string) error {
if len(args) != 1 {
cmdUsage("check-datapath", "<datapath>")
}
if err := createDatapath(args); err != nil {
return err
}
return odp.DeleteDatapath(args[0])
}
func addDatapathInterface(args []string) error {
if len(args) != 2 {
cmdUsage("add-datapath-interface", "<datapath> <interface>")
+2 -1
View File
@@ -17,9 +17,10 @@ func init() {
"help": help,
"netcheck": netcheck,
"docker-tls-args": dockerTLSArgs,
"create-bridge": createBridge,
"detect-bridge-type": detectBridgeType,
"create-datapath": createDatapath,
"delete-datapath": deleteDatapath,
"check-datapath": checkDatapath,
"add-datapath-interface": addDatapathInterface,
"create-plugin-network": createPluginNetwork,
"remove-plugin-network": removePluginNetwork,
+51 -179
View File
@@ -365,15 +365,6 @@ delete_iptables_rule() {
fi
}
# Configure the ARP cache parameters for the given interface. This
# makes containers react more quickly to a change in the MAC address
# associated with an IP address.
configure_arp_cache() {
$2 sh -c "echo 5 >$PROC_PATH/sys/net/ipv4/neigh/$1/base_reachable_time &&
echo 2 >$PROC_PATH/sys/net/ipv4/neigh/$1/delay_first_probe_time &&
echo 1 >$PROC_PATH/sys/net/ipv4/neigh/$1/ucast_solicit"
}
# Send out an ARP announcement
# (https://tools.ietf.org/html/rfc5227#page-15) to update ARP cache
# entries across the weave network. We do this in addition to
@@ -449,29 +440,21 @@ enforce_docker_bridge_addr_assign_type() {
# bridge/datapath devices have yet to be configured. If netdevs do exist
# but are in an inconsistent state the script aborts with an error.
detect_bridge_type() {
BRIDGE_TYPE=
if [ -d /sys/class/net/$DATAPATH ] ; then
# Unfortunately there's no simple way to positively check whether
# $DATAPATH is an ODP netdev so we have to make sure it isn't
# a bridge instead (and that $BRIDGE is).
if [ ! -d /sys/class/net/$DATAPATH/bridge -a -d /sys/class/net/$BRIDGE/bridge ] ; then
BRIDGE_TYPE=bridged_fastdp
else
BRIDGE_TYPE=$(util_op detect-bridge-type "$BRIDGE" "$DATAPATH")
case "$BRIDGE_TYPE" in
bridge|bridged_fastdp)
;;
fastdp)
DATAPATH="$BRIDGE"
;;
inconsistent)
echo "Inconsistent bridge state detected. Please do 'weave reset' and try again." >&2
exit 1
fi
elif [ -d /sys/class/net/$BRIDGE ] ; then
if [ -d /sys/class/net/$BRIDGE/bridge ] ; then
BRIDGE_TYPE=bridge
else
BRIDGE_TYPE=fastdp
# The datapath is the bridge when there is no intermediary
DATAPATH="$BRIDGE"
fi
else
# No bridge/datapath devices configured
return 1
fi
;;
*)
return 1
;;
esac
# WEAVE_MTU may have been specified when the bridge was
# created (perhaps implicitly with WEAVE_NO_FASTDP). So take
@@ -481,46 +464,19 @@ detect_bridge_type() {
}
try_create_bridge() {
if ! detect_bridge_type ; then
BRIDGE_TYPE=bridge
if [ -z "$WEAVE_NO_FASTDP" ] ; then
BRIDGE_TYPE=bridged_fastdp
if [ -n "$WEAVE_NO_BRIDGED_FASTDP" ] ; then
BRIDGE_TYPE=fastdp
# The datapath is the bridge when there is no intermediary
DATAPATH="$BRIDGE"
fi
if util_op create-datapath $DATAPATH ; then
: # ODP datapath created successfully
elif [ $? = 17 ] ; then
# Exit status of 17 means the kernel doesn't have ODP
BRIDGE_TYPE=bridge
else
return 1
fi
fi
# Running this from 'weave --local' when weaveexec is not on the
# path will run it as a Docker container that does not have access
# to /etc/machine-id, so will not give the full range of persistent IDs
if [ -z "$WEAVEDB_DIR_PATH" ]; then
WEAVEDB_DIR_PATH="$HOST_ROOT/$(docker inspect -f '{{with index .Mounts 0}}{{.Source}}{{end}}' $DB_CONTAINER_NAME 2>/dev/null)"
fi
MAC=$(util_op unique-id "$WEAVEDB_DIR_PATH/weave" "$HOST_ROOT")
BRIDGE_TYPE=$(util_op create-bridge "$DOCKER_BRIDGE" "$BRIDGE" "$DATAPATH" "$WEAVE_MTU" "$PORT" "$MAC" "$WEAVE_NO_FASTDP" "$WEAVE_NO_BRIDGED_FASTDP")
# Set some variables that are expected by code that comes later
[ "$BRIDGE_TYPE" != "fastdp" ] || DATAPATH="$BRIDGE"
MTU=${WEAVE_MTU:-$(cat /sys/class/net/$BRIDGE/mtu)}
init_$BRIDGE_TYPE
# Drop traffic from Docker bridge to Weave; it can break
# subnet isolation
if [ "$DOCKER_BRIDGE" != "$BRIDGE" ] ; then
# Note using -I to insert ahead of Docker's bridge rules
run_iptables -t filter -I FORWARD -i $DOCKER_BRIDGE -o $BRIDGE -j DROP
fi
[ -n "$DOCKER_BRIDGE_IP" ] || DOCKER_BRIDGE_IP=$(util_op bridge-ip $DOCKER_BRIDGE)
# forbid traffic to the Weave port from other containers
add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p tcp --dst $DOCKER_BRIDGE_IP --dport $PORT -j DROP
add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p udp --dst $DOCKER_BRIDGE_IP --dport $PORT -j DROP
add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p udp --dst $DOCKER_BRIDGE_IP --dport $(($PORT + 1)) -j DROP
# let DNS traffic to weaveDNS, since otherwise it might get blocked by the likes of UFW
add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p udp --dport 53 -j ACCEPT
add_iptables_rule filter INPUT -i $DOCKER_BRIDGE -p tcp --dport 53 -j ACCEPT
if [ "$2" = "--expect-npc" ] ; then # matches usage in weave-kube launch.sh
if [ "$1" = "--expect-npc" ] ; then # matches usage in weave-kube launch.sh
# Steer traffic via the NPC
run_iptables -N WEAVE-NPC >/dev/null 2>&1 || true
add_iptables_rule filter FORWARD -o $BRIDGE -j WEAVE-NPC
@@ -535,41 +491,10 @@ try_create_bridge() {
add_iptables_rule filter FORWARD -i $BRIDGE ! -o $BRIDGE -j ACCEPT
# and allow replies back
add_iptables_rule filter FORWARD -o $BRIDGE -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# create a chain for masquerading
run_iptables -t nat -N WEAVE >/dev/null 2>&1 || true
add_iptables_rule nat POSTROUTING -j WEAVE
else
if [ -n "$LAUNCHING_ROUTER" ] ; then
if [ "$BRIDGE_TYPE" = bridge -a -z "$WEAVE_NO_FASTDP" ] &&
util_op check-datapath $DATAPATH 2>/dev/null ; then
cat <<EOF >&2
WEAVE_NO_FASTDP is not set, but there is already a bridge present of
the wrong type for fast datapath. Please do 'weave reset' to remove
the bridge first.
EOF
return 1
fi
if [ "$BRIDGE_TYPE" != bridge -a -n "$WEAVE_NO_FASTDP" ] ; then
cat <<EOF >&2
WEAVE_NO_FASTDP is set, but there is already a weave fast datapath
bridge present. Please do 'weave reset' to remove the bridge first.
EOF
return 1
fi
fi
fi
[ "$1" = "--without-ethtool" -o -n "$AWSVPC" ] || ethtool_tx_off_$BRIDGE_TYPE $BRIDGE
ip link set dev $BRIDGE up
# Configure the ARP cache parameters on the bridge interface for
# the sake of 'weave expose'
configure_arp_cache $BRIDGE
}
create_bridge() {
validate_bridge_type
if ! try_create_bridge "$@" ; then
echo "Creating bridge '$BRIDGE' failed" >&2
# reset to original value so we destroy both kinds
@@ -579,6 +504,28 @@ create_bridge() {
fi
}
validate_bridge_type() {
detect_bridge_type || return 0
if [ -n "$LAUNCHING_ROUTER" ] ; then
if [ "$BRIDGE_TYPE" = bridge -a -z "$WEAVE_NO_FASTDP" ] ; then
cat <<EOF >&2
WEAVE_NO_FASTDP is not set, but there is already a bridge present of
the wrong type for fast datapath. Please do 'weave reset' to remove
the bridge first.
EOF
return 1
fi
if [ "$BRIDGE_TYPE" != bridge -a -n "$WEAVE_NO_FASTDP" ] ; then
cat <<EOF >&2
WEAVE_NO_FASTDP is set, but there is already a weave fast datapath
bridge present. Please do 'weave reset' to remove the bridge first.
EOF
return 1
fi
fi
}
expose_ip() {
ipam_cidrs allocate_no_check_alive weave:expose $CIDR_ARGS
for CIDR in $ALL_CIDRS ; do
@@ -614,80 +561,6 @@ create_veth() {
fi
}
init_fastdp() {
# GCE has the lowest underlay network MTU we're likely to encounter on
# a local network, at 1460 bytes. To get the overlay MTU from that we
# subtract 20 bytes for the outer IPv4 header, 8 bytes for the outer
# UDP header, 8 bytes for the vxlan header, and 14 bytes for the inner
# ethernet header. In addition, we subtract 34 bytes for the ESP overhead
# which is needed for the vxlan encryption.
MTU=${WEAVE_MTU:-1376}
# create_bridge already created the datapath netdev
ip link set dev $DATAPATH mtu $MTU
}
init_bridge_prep() {
# Observe any MTU that is already set
[ -n "$MTU" ] || MTU=${WEAVE_MTU:-65535}
ip link add name $BRIDGE type bridge
# Running this from 'weave --local' when weaveexec is not on the
# path will run it as a Docker container that does not have access
# to /etc/machine-id, so will not give the full range of persistent IDs
if [ -z "$WEAVEDB_DIR_PATH" ]; then
WEAVEDB_DIR_PATH="$HOST_ROOT/$(docker inspect -f '{{with index .Mounts 0}}{{.Source}}{{end}}' $DB_CONTAINER_NAME 2>/dev/null)"
fi
MAC=$(util_op unique-id "$WEAVEDB_DIR_PATH/weave" "$HOST_ROOT")
ip link set dev $BRIDGE address $MAC
# Attempting to set the bridge MTU to a high value directly
# fails. Bridges take the lowest MTU of their interfaces. So
# instead we create a temporary interface with the desired
# MTU, attach that to the bridge, and then remove it again.
ip link add name v${CONTAINER_IFNAME}du mtu $MTU type dummy
ip link set dev v${CONTAINER_IFNAME}du master $BRIDGE
ip link del dev v${CONTAINER_IFNAME}du
}
init_bridge() {
init_bridge_prep
create_veth $BRIDGE_IFNAME $PCAP_IFNAME add_iface_bridge $BRIDGE_IFNAME
}
init_bridged_fastdp() {
# Initialise the datapath as normal. NB sets MTU for use below
init_fastdp
# Initialise the bridge using fast datapath MTU
init_bridge_prep
# Create linking veth pair
create_veth $BRIDGE_IFNAME $DATAPATH_IFNAME configure_veth_bridged_fastdp
# Finally, bring the datapath up
ip link set dev $DATAPATH up
}
configure_veth_bridged_fastdp() {
add_iface_fastdp $DATAPATH_IFNAME || return 1
add_iface_bridge $BRIDGE_IFNAME || return 1
}
ethtool_tx_off_fastdp() {
true
}
ethtool_tx_off_bridge() {
ethtool -K $1 tx off >/dev/null
}
ethtool_tx_off_bridged_fastdp() {
true
}
destroy_bridge() {
# It's important that detect_bridge_type has not been called so
# we have distinct values for $BRIDGE and $DATAPATH. Make best efforts
@@ -1854,8 +1727,7 @@ EOF
else
shift 1
fi
create_bridge --without-ethtool "$@"
create_bridge "$@"
;;
attach-bridge)
if detect_bridge_type ; then
@@ -2062,7 +1934,7 @@ EOF
[ $# -eq 2 -a "$1" = "-h" ] || usage
FQDN="$2"
fi
create_bridge --without-ethtool
create_bridge
expose_ip
util_op expose-nat $ALL_CIDRS
show_addrs $ALL_CIDRS
@@ -2071,7 +1943,7 @@ EOF
collect_cidr_args "$@"
shift $CIDR_ARG_COUNT
ipam_cidrs lookup weave:expose $CIDR_ARGS
create_bridge --without-ethtool
create_bridge
for CIDR in $ALL_CIDRS ; do
if ip addr show dev $BRIDGE | grep -qF $CIDR ; then
ip addr del dev $BRIDGE $CIDR