Example #1
0
File: utils.go Project: n054/weave
// Do post-attach configuration of all veths we have created
func ConfigureARPforVeths(processID int, prefix string) error {
	_, err := FindNetDevs(processID, func(link netlink.Link) bool {
		ifName := link.Attrs().Name
		if strings.HasPrefix(ifName, prefix) {
			weavenet.ConfigureARPCache(ifName)
			if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil {
				for _, addr := range addrs {
					arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName)
				}
			}
		}
		return false
	})
	return err
}
Example #2
0
func main() {
	flag.Parse()

	if *helpFlag {
		printHelpAndExit()
	}
	if *verboseFlag {
		arping.EnableVerboseLog()
	}
	arping.SetTimeout(*timeoutFlag)

	if len(flag.Args()) != 1 {
		fmt.Println("Parameter <IP> missing!")
		printHelpAndExit()
	}
	dstIP := net.ParseIP(flag.Arg(0))

	var hwAddr net.HardwareAddr
	var durationNanos time.Duration
	var err error
	if *gratuitousFlag {
		if len(*ifaceNameFlag) > 0 {
			err = arping.GratuitousArpOverIfaceByName(dstIP, *ifaceNameFlag)
		} else {
			err = arping.GratuitousArp(dstIP)
		}
	} else {
		if len(*ifaceNameFlag) > 0 {
			hwAddr, durationNanos, err = arping.PingOverIfaceByName(dstIP, *ifaceNameFlag)
		} else {
			hwAddr, durationNanos, err = arping.Ping(dstIP)
		}
	}

	// ping timeout
	if err == arping.ErrTimeout {
		fmt.Println(err)
		os.Exit(1)
	}

	// ping failed
	if err != nil {
		fmt.Println(err)
		os.Exit(2)
	}

	if *gratuitousFlag {
		os.Exit(0)
	}

	// ping success
	durationMicros := durationNanos / 1000

	var durationString string
	if durationMicros > 1000 {
		durationString = fmt.Sprintf("%d,%03d", durationMicros/1000, durationMicros%1000)
	} else {
		durationString = fmt.Sprintf("%d", durationMicros)
	}

	fmt.Printf("%s (%s) %s usec\n", dstIP, hwAddr, durationString)
	os.Exit(0)
}
Example #3
0
File: veth.go Project: n054/weave
func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool) error {
	ipt, err := iptables.New()
	if err != nil {
		return err
	}

	if !interfaceExistsInNamespace(ns, ifName) {
		maxIDLen := IFNAMSIZ - 1 - len(vethPrefix+"pl")
		if len(id) > maxIDLen {
			id = id[:maxIDLen] // trim passed ID if too long
		}
		name, peerName := vethPrefix+"pl"+id, vethPrefix+"pg"+id
		_, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, func(veth netlink.Link) error {
			if err := netlink.LinkSetNsFd(veth, int(ns)); err != nil {
				return fmt.Errorf("failed to move veth to container netns: %s", err)
			}
			if err := WithNetNSUnsafe(ns, func() error {
				if err := netlink.LinkSetName(veth, ifName); err != nil {
					return err
				}
				if err := ConfigureARPCache(ifName); err != nil {
					return err
				}
				if err := ipt.Append("filter", "INPUT", "-i", ifName, "-d", "224.0.0.0/4", "-j", "DROP"); err != nil {
					return err
				}
				return nil
			}); err != nil {
				return fmt.Errorf("error setting up interface: %s", err)
			}
			return nil
		})
		if err != nil {
			return err
		}
	}

	if err := WithNetNSLinkUnsafe(ns, ifName, func(veth netlink.Link) error {
		newAddresses, err := AddAddresses(veth, cidrs)
		if err != nil {
			return err
		}

		// Add multicast ACCEPT rules for new subnets
		for _, ipnet := range newAddresses {
			acceptRule := []string{"-i", ifName, "-s", subnet(ipnet), "-d", "224.0.0.0/4", "-j", "ACCEPT"}
			exists, err := ipt.Exists("filter", "INPUT", acceptRule...)
			if err != nil {
				return err
			}
			if !exists {
				if err := ipt.Insert("filter", "INPUT", 1, acceptRule...); err != nil {
					return err
				}
			}
		}

		if err := netlink.LinkSetUp(veth); err != nil {
			return err
		}
		for _, ipnet := range newAddresses {
			// If we don't wait for a bit here, we see the arp fail to reach the bridge.
			time.Sleep(1 * time.Millisecond)
			arping.GratuitousArpOverIfaceByName(ipnet.IP, ifName)
		}
		if withMulticastRoute {
			/* Route multicast packets across the weave network.
			This must come last in 'attach'. If you change this, change weavewait to match.

			TODO: Add the MTU lock to prevent PMTU discovery for multicast
			destinations. Without that, the kernel sets the DF flag on
			multicast packets. Since RFC1122 prohibits sending of ICMP
			errors for packets with multicast destinations, that causes
			packets larger than the PMTU to be dropped silently.  */

			_, multicast, _ := net.ParseCIDR("224.0.0.0/4")
			if err := AddRoute(veth, netlink.SCOPE_LINK, multicast, nil); err != nil {
				return err
			}
		}
		return nil
	}); err != nil {
		return err
	}

	return nil
}