diff --git a/net/bridge.go b/net/bridge.go index da0bd40a..6845c0bf 100644 --- a/net/bridge.go +++ b/net/bridge.go @@ -2,6 +2,7 @@ package net import ( "fmt" + "net" "github.com/Sirupsen/logrus" "github.com/vishvananda/netlink" @@ -86,3 +87,24 @@ func DetectHairpin(portIfName string, log *logrus.Logger) error { return nil } + +var ErrBridgeNoIP = fmt.Errorf("Bridge has no IP address") + +func FindBridgeIP(bridgeName string, subnet *net.IPNet) (net.IP, error) { + netdev, err := GetBridgeNetDev(bridgeName) + if err != nil { + return nil, fmt.Errorf("Failed to get netdev for %q bridge: %s", bridgeName, err) + } + if len(netdev.CIDRs) == 0 { + return nil, ErrBridgeNoIP + } + if subnet != nil { + for _, cidr := range netdev.CIDRs { + if subnet.Contains(cidr.IP) { + return cidr.IP, nil + } + } + } + // No subnet, or none in the required subnet; just return the first one + return netdev.CIDRs[0].IP, nil +} diff --git a/plugin/net/cni.go b/plugin/net/cni.go index 3145e49d..5ed1c35a 100644 --- a/plugin/net/cni.go +++ b/plugin/net/cni.go @@ -73,8 +73,8 @@ func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error { // If config says nothing about routes or gateway, default one will be via the bridge if result.IP4.Routes == nil && result.IP4.Gateway == nil { - bridgeIP, err := findBridgeIP(conf.BrName, result.IP4.IP) - if err == errBridgeNoIP { + bridgeIP, err := weavenet.FindBridgeIP(conf.BrName, &result.IP4.IP) + if err == weavenet.ErrBridgeNoIP { bridgeArgs := *args bridgeArgs.ContainerID = "weave:expose" bridgeIPResult, err := c.getIP(conf.IPAM.Type, &bridgeArgs) @@ -164,25 +164,6 @@ func assignBridgeIP(bridgeName string, ipnet net.IPNet) error { return nil } -var errBridgeNoIP = fmt.Errorf("Bridge has no IP address") - -func findBridgeIP(bridgeName string, subnet net.IPNet) (net.IP, error) { - netdev, err := weavenet.GetBridgeNetDev(bridgeName) - if err != nil { - return nil, fmt.Errorf("Failed to get netdev for %q bridge: %s", bridgeName, err) - } - if len(netdev.CIDRs) == 0 { - return nil, errBridgeNoIP - } - for _, cidr := range netdev.CIDRs { - if subnet.Contains(cidr.IP) { - return cidr.IP, nil - } - } - // None in the required subnet; just return the first one - return netdev.CIDRs[0].IP, nil -} - func (c *CNIPlugin) CmdDel(args *skel.CmdArgs) error { conf, err := loadNetConf(args.StdinData) if err != nil { diff --git a/prog/weaveutil/addrs.go b/prog/weaveutil/addrs.go index 8c18ee20..e48a9aa5 100644 --- a/prog/weaveutil/addrs.go +++ b/prog/weaveutil/addrs.go @@ -77,3 +77,16 @@ func printNetDevs(cid string, netDevs []weavenet.Dev) { fmt.Println() } } + +func bridgeIP(args []string) error { + if len(args) < 1 { + cmdUsage("bridge-ip", "") + } + bridgeName := args[0] + ip, err := weavenet.FindBridgeIP(bridgeName, nil) + if err != nil { + return err + } + fmt.Printf("%v", ip) + return nil +} diff --git a/prog/weaveutil/main.go b/prog/weaveutil/main.go index b4dabc65..8322a013 100644 --- a/prog/weaveutil/main.go +++ b/prog/weaveutil/main.go @@ -35,6 +35,7 @@ func init() { "cni-net": cniNet, "cni-ipam": cniIPAM, "expose-nat": exposeNAT, + "bridge-ip": bridgeIP, } } diff --git a/proxy/proxy.go b/proxy/proxy.go index be71befd..e753ae26 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -148,14 +148,12 @@ func NewProxy(c Config) (*Proxy, error) { p.client = client.Client if !p.WithoutDNS { - netDev, err := weavenet.GetBridgeNetDev(c.DockerBridge) + ip, err := weavenet.FindBridgeIP(c.DockerBridge, nil) if err != nil { return nil, err } - if len(netDev.CIDRs) != 1 { - return nil, fmt.Errorf("Could not obtain address of %s", c.DockerBridge) - } - p.dockerBridgeIP = netDev.CIDRs[0].IP.String() + p.dockerBridgeIP = ip.String() + Log.Infof("Using docker bridge IP for DNS: %v", p.dockerBridgeIP) } p.hostnameMatchRegexp, err = regexp.Compile(c.HostnameMatch) diff --git a/weave b/weave index 37fb4ef2..ead763ce 100755 --- a/weave +++ b/weave @@ -602,7 +602,7 @@ try_create_bridge() { run_iptables -t filter -I FORWARD -i $DOCKER_BRIDGE -o $BRIDGE -j DROP fi - [ -n "$DOCKER_BRIDGE_IP" ] || docker_bridge_ip + [ -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 @@ -803,7 +803,7 @@ destroy_bridge() { run_iptables -t filter -D FORWARD -i $DOCKER_BRIDGE -o $BRIDGE -j DROP 2>/dev/null || true fi - [ -n "$DOCKER_BRIDGE_IP" ] || docker_bridge_ip + [ -n "$DOCKER_BRIDGE_IP" ] || DOCKER_BRIDGE_IP=$(util_op bridge-ip $DOCKER_BRIDGE) run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p udp --dport 53 -j ACCEPT >/dev/null 2>&1 || true run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p tcp --dport 53 -j ACCEPT >/dev/null 2>&1 || true @@ -824,11 +824,6 @@ destroy_bridge() { run_iptables -t nat -X WEAVE >/dev/null 2>&1 || true } -docker_bridge_ip() { - DOCKER_BRIDGE_IP=$(ip -4 addr show dev $DOCKER_BRIDGE | grep -m1 -o 'inet [.0-9]*') || return 1 - DOCKER_BRIDGE_IP=${DOCKER_BRIDGE_IP#inet } -} - do_or_die() { CONTAINER="$1" shift 1 @@ -1132,7 +1127,7 @@ dns_args() { done [ -n "$WITHOUT_DNS" ] && return 0 - docker_bridge_ip + [ -n "$DOCKER_BRIDGE_IP" ] || DOCKER_BRIDGE_IP=$(util_op bridge-ip $DOCKER_BRIDGE) DNS_ARGS="--dns=$DOCKER_BRIDGE_IP" if [ -n "$NAME_ARG" -a -z "$HOSTNAME_SPECIFIED" ] ; then HOSTNAME="$NAME_ARG.${DNS_DOMAIN%.}" @@ -1594,7 +1589,7 @@ launch_router() { IPRANGE= IPRANGE_SPECIFIED= - docker_bridge_ip + [ -n "$DOCKER_BRIDGE_IP" ] || DOCKER_BRIDGE_IP=$(util_op bridge-ip $DOCKER_BRIDGE) DNS_ROUTER_OPTS="--dns-listen-address $DOCKER_BRIDGE_IP:53" NO_DNS_OPT= @@ -2135,8 +2130,7 @@ EOF echo -n $DNS_ARGS ;; docker-bridge-ip) - docker_bridge_ip - echo -n $DOCKER_BRIDGE_IP + util_op bridge-ip $DOCKER_BRIDGE ;; start) collect_cidr_args "$@" @@ -2234,7 +2228,7 @@ EOF ;; dns-lookup) [ $# -eq 1 ] || usage - docker_bridge_ip + DOCKER_BRIDGE_IP=$(util_op bridge-ip $DOCKER_BRIDGE) dig @$DOCKER_BRIDGE_IP +short $1 ;; expose)