in pkg/skoop/plugin/calico.go [552:615]
func (h *calicoHost) to(upstream *model.Link, dst model.Endpoint, protocol model.Protocol, transmit transmissionFunc) ([]model.Transmission, error) {
iif, err := h.detectIif(upstream)
if err != nil {
return nil, err
}
var action *model.Action
var transmission model.Transmission
var pkt *model.Packet
var nfAssertionFunc func(pktIn model.Packet, pktOut []model.Packet, iif string)
if upstream != nil {
if upstream.Type == model.LinkVeth {
h.assertInterface(iif)
}
upstream.Destination = h.netNode
upstream.DestinationAttribute = model.SimpleLinkAttribute{Interface: iif}
pkt = h.Decap(upstream.Packet)
transmission, err = transmit(pkt, iif)
if err != nil {
return nil, err
}
if transmission.Link == nil {
return nil, nil
}
nfAssertionFunc = h.net.AssertNetfilterForward
action = model.ActionForward(upstream, []*model.Link{transmission.Link})
} else {
pkt = &model.Packet{
Dst: net.ParseIP(dst.IP),
Dport: dst.Port,
Protocol: protocol,
}
addr, _, err := h.nodeInfo.Router.RouteSrc(pkt, "", "")
if err != nil {
if err == netstack.ErrNoRouteToHost {
h.netNode.AddSuspicion(model.SuspicionLevelFatal, fmt.Sprintf("no route to host: %v", dst))
return nil, &assertions.CannotBuildTransmissionError{
SrcNode: h.netNode,
Err: fmt.Errorf("no route to host: %v", err),
}
}
return nil, err
}
pkt.Src = net.ParseIP(addr)
transmission, err = transmit(pkt, iif)
if err != nil {
return nil, err
}
if transmission.Link == nil {
return nil, nil
}
nfAssertionFunc = h.net.AssertNetfilterSend
action = model.ActionSend([]*model.Link{transmission.Link})
}
pktOut := transmission.Link.Packet
nfAssertionFunc(*pkt, []model.Packet{*pktOut}, iif)
h.netNode.DoAction(action)
return []model.Transmission{transmission}, nil
}