Move bridge-creation code from weave script into Go code
via weaveutil create-bridge function
This commit is contained in:
1 parent
6fd9f471ff
commit
8051f51d46
5 files changed
+115
-195
No files matched your search
+17
-2
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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>")
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user