|
@@ -19,11 +19,9 @@ import (
|
|
|
"net"
|
|
|
"os"
|
|
|
"syscall"
|
|
|
- "time"
|
|
|
|
|
|
log "github.com/coreos/flannel/Godeps/_workspace/src/github.com/golang/glog"
|
|
|
"github.com/coreos/flannel/Godeps/_workspace/src/github.com/vishvananda/netlink"
|
|
|
- "github.com/coreos/flannel/Godeps/_workspace/src/github.com/vishvananda/netlink/nl"
|
|
|
|
|
|
"github.com/coreos/flannel/pkg/ip"
|
|
|
)
|
|
@@ -60,9 +58,7 @@ func newVXLANDevice(devAttrs *vxlanDeviceAttrs) (*vxlanDevice, error) {
|
|
|
VtepDevIndex: devAttrs.vtepIndex,
|
|
|
SrcAddr: devAttrs.vtepAddr,
|
|
|
Port: devAttrs.vtepPort,
|
|
|
- Learning: true,
|
|
|
- Proxy: true,
|
|
|
- L2miss: true,
|
|
|
+ Learning: false,
|
|
|
}
|
|
|
|
|
|
link, err := ensureLink(link)
|
|
@@ -70,10 +66,6 @@ func newVXLANDevice(devAttrs *vxlanDeviceAttrs) (*vxlanDevice, error) {
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
- // this enables ARP requests being sent to userspace via netlink
|
|
|
- sysctlPath := fmt.Sprintf("/proc/sys/net/ipv4/neigh/%s/app_solicit", devAttrs.name)
|
|
|
- sysctlSet(sysctlPath, "3")
|
|
|
-
|
|
|
return &vxlanDevice{
|
|
|
link: link,
|
|
|
}, nil
|
|
@@ -153,94 +145,75 @@ func (dev *vxlanDevice) MTU() int {
|
|
|
return dev.link.MTU
|
|
|
}
|
|
|
|
|
|
-func (dev *vxlanDevice) MonitorMisses(misses chan *netlink.Neigh) {
|
|
|
- nlsock, err := nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH)
|
|
|
- if err != nil {
|
|
|
- log.Error("Failed to subscribe to netlink RTNLGRP_NEIGH messages")
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- for {
|
|
|
- msgs, err := nlsock.Receive()
|
|
|
- if err != nil {
|
|
|
- log.Errorf("Failed to receive from netlink: %v ", err)
|
|
|
-
|
|
|
- // wait 1 sec before retrying but honor the cancel channel
|
|
|
- time.Sleep(1 * time.Second)
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- for _, msg := range msgs {
|
|
|
- dev.processNeighMsg(msg, misses)
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func isNeighResolving(state int) bool {
|
|
|
- return (state & (netlink.NUD_INCOMPLETE | netlink.NUD_STALE | netlink.NUD_DELAY | netlink.NUD_PROBE)) != 0
|
|
|
-}
|
|
|
-
|
|
|
-func (dev *vxlanDevice) processNeighMsg(msg syscall.NetlinkMessage, misses chan *netlink.Neigh) {
|
|
|
- neigh, err := netlink.NeighDeserialize(msg.Data)
|
|
|
- if err != nil {
|
|
|
- log.Error("Failed to deserialize netlink ndmsg: %v", err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if int(neigh.LinkIndex) != dev.link.Index {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if msg.Header.Type != syscall.RTM_GETNEIGH && msg.Header.Type != syscall.RTM_NEWNEIGH {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if !isNeighResolving(neigh.State) {
|
|
|
- // misses come with NUD_STALE bit set
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- misses <- neigh
|
|
|
+type neigh struct {
|
|
|
+ MAC net.HardwareAddr
|
|
|
+ IP ip.IP4
|
|
|
}
|
|
|
|
|
|
-func (dev *vxlanDevice) AddL2(mac net.HardwareAddr, vtep net.IP) error {
|
|
|
- neigh := netlink.Neigh{
|
|
|
+func (dev *vxlanDevice) AddL2(n neigh) error {
|
|
|
+ log.Infof("calling NeighAdd: %v, %v", n.IP, n.MAC)
|
|
|
+ return netlink.NeighAdd(&netlink.Neigh{
|
|
|
LinkIndex: dev.link.Index,
|
|
|
- State: netlink.NUD_REACHABLE,
|
|
|
+ State: netlink.NUD_PERMANENT,
|
|
|
Family: syscall.AF_BRIDGE,
|
|
|
Flags: netlink.NTF_SELF,
|
|
|
- IP: vtep,
|
|
|
- HardwareAddr: mac,
|
|
|
- }
|
|
|
-
|
|
|
- log.Infof("calling NeighAdd: %v, %v", vtep, mac)
|
|
|
- return netlink.NeighAdd(&neigh)
|
|
|
+ IP: n.IP.ToIP(),
|
|
|
+ HardwareAddr: n.MAC,
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
-func (dev *vxlanDevice) DelL2(mac net.HardwareAddr, vtep net.IP) error {
|
|
|
- neigh := netlink.Neigh{
|
|
|
+func (dev *vxlanDevice) DelL2(n neigh) error {
|
|
|
+ log.Infof("calling NeighDel: %v, %v", n.IP, n.MAC)
|
|
|
+ return netlink.NeighDel(&netlink.Neigh{
|
|
|
LinkIndex: dev.link.Index,
|
|
|
Family: syscall.AF_BRIDGE,
|
|
|
Flags: netlink.NTF_SELF,
|
|
|
- IP: vtep,
|
|
|
- HardwareAddr: mac,
|
|
|
- }
|
|
|
+ IP: n.IP.ToIP(),
|
|
|
+ HardwareAddr: n.MAC,
|
|
|
+ })
|
|
|
+}
|
|
|
|
|
|
- log.Infof("calling NeighDel: %v, %v", vtep, mac)
|
|
|
- return netlink.NeighDel(&neigh)
|
|
|
+func (dev *vxlanDevice) AddL3(n neigh) error {
|
|
|
+ log.Infof("calling NeighSet: %v, %v", n.IP, n.MAC)
|
|
|
+ return netlink.NeighSet(&netlink.Neigh{
|
|
|
+ LinkIndex: dev.link.Index,
|
|
|
+ State: netlink.NUD_PERMANENT,
|
|
|
+ Type: syscall.RTN_UNICAST,
|
|
|
+ IP: n.IP.ToIP(),
|
|
|
+ HardwareAddr: n.MAC,
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
-func (dev *vxlanDevice) AddL3(ip net.IP, mac net.HardwareAddr) error {
|
|
|
- neigh := netlink.Neigh{
|
|
|
+func (dev *vxlanDevice) DelL3(n neigh) error {
|
|
|
+ log.Infof("calling NeighDel: %v, %v", n.IP, n.MAC)
|
|
|
+ return netlink.NeighDel(&netlink.Neigh{
|
|
|
LinkIndex: dev.link.Index,
|
|
|
- State: netlink.NUD_REACHABLE,
|
|
|
+ State: netlink.NUD_PERMANENT,
|
|
|
Type: syscall.RTN_UNICAST,
|
|
|
- IP: ip,
|
|
|
- HardwareAddr: mac,
|
|
|
+ IP: n.IP.ToIP(),
|
|
|
+ HardwareAddr: n.MAC,
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+func (dev *vxlanDevice) AddRoute(subnet ip.IP4Net) error {
|
|
|
+ route := &netlink.Route{
|
|
|
+ Scope: netlink.SCOPE_UNIVERSE,
|
|
|
+ Dst: subnet.ToIPNet(),
|
|
|
+ Gw: subnet.IP.ToIP(),
|
|
|
}
|
|
|
|
|
|
- log.Infof("calling NeighSet: %v, %v", ip, mac)
|
|
|
- return netlink.NeighSet(&neigh)
|
|
|
+ log.Infof("calling RouteAdd: %s", subnet)
|
|
|
+ return netlink.RouteAdd(route)
|
|
|
+}
|
|
|
+
|
|
|
+func (dev *vxlanDevice) DelRoute(subnet ip.IP4Net) error {
|
|
|
+ route := &netlink.Route{
|
|
|
+ Scope: netlink.SCOPE_UNIVERSE,
|
|
|
+ Dst: subnet.ToIPNet(),
|
|
|
+ Gw: subnet.IP.ToIP(),
|
|
|
+ }
|
|
|
+ log.Infof("calling RouteDel: %s", subnet)
|
|
|
+ return netlink.RouteDel(route)
|
|
|
}
|
|
|
|
|
|
func vxlanLinksIncompat(l1, l2 netlink.Link) string {
|