diff --git a/net/bridge.go b/net/bridge.go index a88a7334..533942d7 100644 --- a/net/bridge.go +++ b/net/bridge.go @@ -173,6 +173,7 @@ type BridgeConfig struct { DatapathName string NoFastdp bool NoBridgedFastdp bool + ExpectNPC bool MTU int Mac string Port int @@ -349,14 +350,36 @@ func configureIPTables(config *BridgeConfig) error { } } - // Work around the situation where there are no rules allowing traffic - // across our bridge. E.g. ufw - if err = ipt.AppendUnique("filter", "FORWARD", "-i", config.WeaveBridgeName, "-o", config.WeaveBridgeName, "-j", "ACCEPT"); err != nil { - return err + if config.ExpectNPC { + // Steer traffic via the NPC + ipt.NewChain("filter", "WEAVE-NPC") // ignoring errors such as 'chain already exists' + if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-j", "WEAVE-NPC"); err != nil { + return err + } + if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-m", "state", "--state", "NEW", "-j", "NFLOG", "--nflog-group", "86"); err != nil { + return err + } + if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-j", "DROP"); err != nil { + return err + } + } else { + // Work around the situation where there are no rules allowing traffic + // across our bridge. E.g. ufw + if err = ipt.AppendUnique("filter", "FORWARD", "-i", config.WeaveBridgeName, "-o", config.WeaveBridgeName, "-j", "ACCEPT"); err != nil { + return err + } + // Forward from weave to the rest of the world + if err = ipt.AppendUnique("filter", "FORWARD", "-i", config.WeaveBridgeName, "!", "-o", config.WeaveBridgeName, "-j", "ACCEPT"); err != nil { + return err + } + // and allow replies back + if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"); err != nil { + return err + } } // create a chain for masquerading - ipt.NewChain("nat", "WEAVE") + ipt.NewChain("nat", "WEAVE") // ignoring errors such as 'chain already exists' if err = ipt.AppendUnique("nat", "POSTROUTING", "-j", "WEAVE"); err != nil { return err } diff --git a/prog/weaveutil/bridge.go b/prog/weaveutil/bridge.go index 4916899a..0b63b336 100644 --- a/prog/weaveutil/bridge.go +++ b/prog/weaveutil/bridge.go @@ -17,8 +17,8 @@ func detectBridgeType(args []string) error { } func createBridge(args []string) error { - if len(args) != 8 { - cmdUsage("create-bridge", " ") + if len(args) != 9 { + cmdUsage("create-bridge", " ") } mtu, err := strconv.Atoi(args[3]) @@ -38,6 +38,7 @@ func createBridge(args []string) error { Mac: args[5], NoFastdp: args[6] != "", NoBridgedFastdp: args[7] != "", + ExpectNPC: args[8] == "--expect-npc", } bridgeType, err := weavenet.CreateBridge(&config) fmt.Println(bridgeType.String()) diff --git a/weave b/weave index 6391a62d..88d9e494 100755 --- a/weave +++ b/weave @@ -326,21 +326,6 @@ run_iptables() { iptables $IPTABLES_W "$@" } -# Add a rule to iptables, if it doesn't exist already -add_iptables_rule() { - IPTABLES_TABLE="$1" - shift 1 - if ! run_iptables -t $IPTABLES_TABLE -C "$@" >/dev/null 2>&1 ; then - ## Loop until we get an exit code other than "temporarily unavailable" - while true ; do - run_iptables -t $IPTABLES_TABLE -A "$@" >/dev/null && return 0 - if [ $? != 4 ] ; then - return 1 - fi - done - fi -} - # Insert a rule in iptables, if it doesn't exist already insert_iptables_rule() { IPTABLES_TABLE="$1" @@ -445,26 +430,10 @@ try_create_bridge() { 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") + BRIDGE_TYPE=$(util_op create-bridge "$DOCKER_BRIDGE" "$BRIDGE" "$DATAPATH" "$WEAVE_MTU" "$PORT" "$MAC" "$WEAVE_NO_FASTDP" "$WEAVE_NO_BRIDGED_FASTDP" "$1") # 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)} - - 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 - add_iptables_rule filter FORWARD -o $BRIDGE -m state --state NEW -j NFLOG --nflog-group 86 - add_iptables_rule filter FORWARD -o $BRIDGE -j DROP - else - # Work around the situation where there are no rules allowing traffic - # across our bridge. E.g. ufw - add_iptables_rule filter FORWARD -i $BRIDGE -o $BRIDGE -j ACCEPT - fi - # Forward from weave to the rest of the world - 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_bridge() {