Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backend/vxlan: Make variables more verbose #575

Merged
merged 1 commit into from
Jan 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions backend/vxlan/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ func ensureLink(vxlan *netlink.Vxlan) (*netlink.Vxlan, error) {
if err != nil {
return nil, fmt.Errorf("can't locate created vxlan device with index %v", ifindex)
}

var ok bool
if vxlan, ok = link.(*netlink.Vxlan); !ok {
return nil, fmt.Errorf("created vxlan device with index %v is not vxlan", ifindex)
Expand Down Expand Up @@ -154,7 +155,7 @@ func (dev *vxlanDevice) MTU() int {
return dev.link.MTU
}

type neigh struct {
type neighbor struct {
MAC net.HardwareAddr
IP ip.IP4
}
Expand All @@ -164,7 +165,7 @@ func (dev *vxlanDevice) GetL2List() ([]netlink.Neigh, error) {
return netlink.NeighList(dev.link.Index, syscall.AF_BRIDGE)
}

func (dev *vxlanDevice) AddL2(n neigh) error {
func (dev *vxlanDevice) AddL2(n neighbor) error {
log.V(4).Infof("calling NeighAdd: %v, %v", n.IP, n.MAC)
return netlink.NeighAdd(&netlink.Neigh{
LinkIndex: dev.link.Index,
Expand All @@ -176,7 +177,7 @@ func (dev *vxlanDevice) AddL2(n neigh) error {
})
}

func (dev *vxlanDevice) DelL2(n neigh) error {
func (dev *vxlanDevice) DelL2(n neighbor) error {
log.V(4).Infof("calling NeighDel: %v, %v", n.IP, n.MAC)
return netlink.NeighDel(&netlink.Neigh{
LinkIndex: dev.link.Index,
Expand All @@ -187,7 +188,7 @@ func (dev *vxlanDevice) DelL2(n neigh) error {
})
}

func (dev *vxlanDevice) AddL3(n neigh) error {
func (dev *vxlanDevice) AddL3(n neighbor) error {
log.V(4).Infof("calling NeighSet: %v, %v", n.IP, n.MAC)
return netlink.NeighSet(&netlink.Neigh{
LinkIndex: dev.link.Index,
Expand All @@ -198,7 +199,7 @@ func (dev *vxlanDevice) AddL3(n neigh) error {
})
}

func (dev *vxlanDevice) DelL3(n neigh) error {
func (dev *vxlanDevice) DelL3(n neighbor) error {
log.V(4).Infof("calling NeighDel: %v, %v", n.IP, n.MAC)
return netlink.NeighDel(&netlink.Neigh{
LinkIndex: dev.link.Index,
Expand Down
118 changes: 59 additions & 59 deletions backend/vxlan/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,51 +33,51 @@ import (

type network struct {
backend.SimpleNetwork
name string
extIface *backend.ExternalInterface
dev *vxlanDevice
rts routes
sm subnet.Manager
name string
extIface *backend.ExternalInterface
dev *vxlanDevice
routes routes
subnetMgr subnet.Manager
}

func newNetwork(name string, sm subnet.Manager, extIface *backend.ExternalInterface, dev *vxlanDevice, nw ip.IP4Net, l *subnet.Lease) (*network, error) {
n := &network{
func newNetwork(name string, subnetMgr subnet.Manager, extIface *backend.ExternalInterface, dev *vxlanDevice, _ ip.IP4Net, lease *subnet.Lease) (*network, error) {
nw := &network{
SimpleNetwork: backend.SimpleNetwork{
SubnetLease: l,
SubnetLease: lease,
ExtIface: extIface,
},
name: name,
sm: sm,
dev: dev,
name: name,
subnetMgr: subnetMgr,
dev: dev,
}

return n, nil
return nw, nil
}

func (n *network) Run(ctx context.Context) {
func (nw *network) Run(ctx context.Context) {
log.V(0).Info("Watching for L3 misses")
misses := make(chan *netlink.Neigh, 100)
// Unfortunately MonitorMisses does not take a cancel channel
// as there's no wait to interrupt netlink socket recv
go n.dev.MonitorMisses(misses)
go nw.dev.MonitorMisses(misses)

wg := sync.WaitGroup{}

log.V(0).Info("Watching for new subnet leases")
evts := make(chan []subnet.Event)
events := make(chan []subnet.Event)
wg.Add(1)
go func() {
subnet.WatchLeases(ctx, n.sm, n.name, n.SubnetLease, evts)
subnet.WatchLeases(ctx, nw.subnetMgr, nw.name, nw.SubnetLease, events)
log.V(1).Info("WatchLeases exited")
wg.Done()
}()

defer wg.Wait()

select {
case initialEvtsBatch := <-evts:
case initialEventsBatch := <-events:
for {
err := n.handleInitialSubnetEvents(initialEvtsBatch)
err := nw.handleInitialSubnetEvents(initialEventsBatch)
if err == nil {
break
}
Expand All @@ -92,72 +92,72 @@ func (n *network) Run(ctx context.Context) {
for {
select {
case miss := <-misses:
n.handleMiss(miss)
nw.handleMiss(miss)

case evtBatch := <-evts:
n.handleSubnetEvents(evtBatch)
case evtBatch := <-events:
nw.handleSubnetEvents(evtBatch)

case <-ctx.Done():
return
}
}
}

func (n *network) MTU() int {
return n.dev.MTU()
func (nw *network) MTU() int {
return nw.dev.MTU()
}

type vxlanLeaseAttrs struct {
VtepMAC hardwareAddr
}

func (n *network) handleSubnetEvents(batch []subnet.Event) {
for _, evt := range batch {
switch evt.Type {
func (nw *network) handleSubnetEvents(batch []subnet.Event) {
for _, event := range batch {
switch event.Type {
case subnet.EventAdded:
log.V(1).Info("Subnet added: ", evt.Lease.Subnet)
log.V(1).Info("Subnet added: ", event.Lease.Subnet)

if evt.Lease.Attrs.BackendType != "vxlan" {
log.Warningf("Ignoring non-vxlan subnet: type=%v", evt.Lease.Attrs.BackendType)
if event.Lease.Attrs.BackendType != "vxlan" {
log.Warningf("Ignoring non-vxlan subnet: type=%v", event.Lease.Attrs.BackendType)
continue
}

var attrs vxlanLeaseAttrs
if err := json.Unmarshal(evt.Lease.Attrs.BackendData, &attrs); err != nil {
if err := json.Unmarshal(event.Lease.Attrs.BackendData, &attrs); err != nil {
log.Error("Error decoding subnet lease JSON: ", err)
continue
}
n.rts.set(evt.Lease.Subnet, net.HardwareAddr(attrs.VtepMAC))
n.dev.AddL2(neigh{IP: evt.Lease.Attrs.PublicIP, MAC: net.HardwareAddr(attrs.VtepMAC)})
nw.routes.set(event.Lease.Subnet, net.HardwareAddr(attrs.VtepMAC))
nw.dev.AddL2(neighbor{IP: event.Lease.Attrs.PublicIP, MAC: net.HardwareAddr(attrs.VtepMAC)})

case subnet.EventRemoved:
log.V(1).Info("Subnet removed: ", evt.Lease.Subnet)
log.V(1).Info("Subnet removed: ", event.Lease.Subnet)

if evt.Lease.Attrs.BackendType != "vxlan" {
log.Warningf("Ignoring non-vxlan subnet: type=%v", evt.Lease.Attrs.BackendType)
if event.Lease.Attrs.BackendType != "vxlan" {
log.Warningf("Ignoring non-vxlan subnet: type=%v", event.Lease.Attrs.BackendType)
continue
}

var attrs vxlanLeaseAttrs
if err := json.Unmarshal(evt.Lease.Attrs.BackendData, &attrs); err != nil {
if err := json.Unmarshal(event.Lease.Attrs.BackendData, &attrs); err != nil {
log.Error("Error decoding subnet lease JSON: ", err)
continue
}

if len(attrs.VtepMAC) > 0 {
n.dev.DelL2(neigh{IP: evt.Lease.Attrs.PublicIP, MAC: net.HardwareAddr(attrs.VtepMAC)})
nw.dev.DelL2(neighbor{IP: event.Lease.Attrs.PublicIP, MAC: net.HardwareAddr(attrs.VtepMAC)})
}
n.rts.remove(evt.Lease.Subnet)
nw.routes.remove(event.Lease.Subnet)

default:
log.Error("Internal error: unknown event type: ", int(evt.Type))
log.Error("Internal error: unknown event type: ", int(event.Type))
}
}
}

func (n *network) handleInitialSubnetEvents(batch []subnet.Event) error {
func (nw *network) handleInitialSubnetEvents(batch []subnet.Event) error {
log.V(1).Infof("Handling initial subnet events")
fdbTable, err := n.dev.GetL2List()
fdbTable, err := nw.dev.GetL2List()
if err != nil {
return fmt.Errorf("error fetching L2 table: %v", err)
}
Expand All @@ -168,54 +168,54 @@ func (n *network) handleInitialSubnetEvents(batch []subnet.Event) error {
}

// "marked" events are skipped at the end.
evtMarker := make([]bool, len(batch))
eventMarker := make([]bool, len(batch))
leaseAttrsList := make([]vxlanLeaseAttrs, len(batch))
fdbEntryMarker := make([]bool, len(fdbTable))

// Run through the events "marking" ones that should be skipped
for i, evt := range batch {
for eventMarkerIndex, evt := range batch {
if evt.Lease.Attrs.BackendType != "vxlan" {
log.Warningf("Ignoring non-vxlan subnet(%s): type=%v", evt.Lease.Subnet, evt.Lease.Attrs.BackendType)
evtMarker[i] = true
eventMarker[eventMarkerIndex] = true
continue
}

// Parse the vxlan specific backend data
if err := json.Unmarshal(evt.Lease.Attrs.BackendData, &leaseAttrsList[i]); err != nil {
if err := json.Unmarshal(evt.Lease.Attrs.BackendData, &leaseAttrsList[eventMarkerIndex]); err != nil {
log.Error("Error decoding subnet lease JSON: ", err)
evtMarker[i] = true
eventMarker[eventMarkerIndex] = true
continue
}

// Check the existing VTEP->Public IP mappings.
// If there's already an entry with the right VTEP and Public IP then the event can be skipped and the FDB entry can be retained
for j, fdbEntry := range fdbTable {
if evt.Lease.Attrs.PublicIP.ToIP().Equal(fdbEntry.IP) && bytes.Equal([]byte(leaseAttrsList[i].VtepMAC), []byte(fdbEntry.HardwareAddr)) {
evtMarker[i] = true
if evt.Lease.Attrs.PublicIP.ToIP().Equal(fdbEntry.IP) && bytes.Equal([]byte(leaseAttrsList[eventMarkerIndex].VtepMAC), []byte(fdbEntry.HardwareAddr)) {
eventMarker[eventMarkerIndex] = true
fdbEntryMarker[j] = true
break
}
}

// Store off the subnet lease and VTEP
n.rts.set(evt.Lease.Subnet, net.HardwareAddr(leaseAttrsList[i].VtepMAC))
log.V(2).Infof("Adding subnet: %s PublicIP: %s VtepMAC: %s", evt.Lease.Subnet, evt.Lease.Attrs.PublicIP, net.HardwareAddr(leaseAttrsList[i].VtepMAC))
nw.routes.set(evt.Lease.Subnet, net.HardwareAddr(leaseAttrsList[eventMarkerIndex].VtepMAC))
log.V(2).Infof("Adding subnet: %s PublicIP: %s VtepMAC: %s", evt.Lease.Subnet, evt.Lease.Attrs.PublicIP, net.HardwareAddr(leaseAttrsList[eventMarkerIndex].VtepMAC))
}

// Loop over the existing FDB entries, deleting any that shouldn't be there
for j, marker := range fdbEntryMarker {
if !marker && fdbTable[j].IP != nil {
err := n.dev.DelL2(neigh{IP: ip.FromIP(fdbTable[j].IP), MAC: fdbTable[j].HardwareAddr})
err := nw.dev.DelL2(neighbor{IP: ip.FromIP(fdbTable[j].IP), MAC: fdbTable[j].HardwareAddr})
if err != nil {
log.Error("Delete L2 failed: ", err)
}
}
}

// Loop over the events (skipping marked ones), adding them to the FDB table.
for i, marker := range evtMarker {
for i, marker := range eventMarker {
if !marker {
err := n.dev.AddL2(neigh{IP: batch[i].Lease.Attrs.PublicIP, MAC: net.HardwareAddr(leaseAttrsList[i].VtepMAC)})
err := nw.dev.AddL2(neighbor{IP: batch[i].Lease.Attrs.PublicIP, MAC: net.HardwareAddr(leaseAttrsList[i].VtepMAC)})
if err != nil {
log.Error("Add L2 failed: ", err)
}
Expand All @@ -224,27 +224,27 @@ func (n *network) handleInitialSubnetEvents(batch []subnet.Event) error {
return nil
}

func (n *network) handleMiss(miss *netlink.Neigh) {
func (nw *network) handleMiss(miss *netlink.Neigh) {
switch {
case len(miss.IP) == 0 && len(miss.HardwareAddr) == 0:
log.V(2).Info("Ignoring nil miss")

case len(miss.HardwareAddr) == 0:
n.handleL3Miss(miss)
nw.handleL3Miss(miss)

default:
log.V(4).Infof("Ignoring not a miss: %v, %v", miss.HardwareAddr, miss.IP)
}
}

func (n *network) handleL3Miss(miss *netlink.Neigh) {
rt := n.rts.findByNetwork(ip.FromIP(miss.IP))
if rt == nil {
func (nw *network) handleL3Miss(miss *netlink.Neigh) {
route := nw.routes.findByNetwork(ip.FromIP(miss.IP))
if route == nil {
log.V(0).Infof("L3 miss but route for %v not found", miss.IP)
return
}

if err := n.dev.AddL3(neigh{IP: ip.FromIP(miss.IP), MAC: rt.vtepMAC}); err != nil {
if err := nw.dev.AddL3(neighbor{IP: ip.FromIP(miss.IP), MAC: route.vtepMAC}); err != nil {
log.Errorf("AddL3 failed: %v", err)
} else {
log.V(2).Infof("L3 miss: AddL3 for %s succeeded", miss.IP)
Expand Down
Loading