in pkg/skoop/plugin/simple.go [58:125]
func (p *simpleVEthPod) Send(dst model.Endpoint, protocol model.Protocol) ([]model.Transmission, error) {
err := p.assert()
if err != nil {
return nil, err
}
pkt := &model.Packet{
Dst: net.ParseIP(dst.IP),
Dport: dst.Port,
Protocol: protocol,
}
addr, dstRoute, err := p.podInfo.NetNS.Router.RouteSrc(pkt, "", "")
if err != nil {
if err == netstack.ErrNoRouteToHost {
p.netNode.AddSuspicion(model.SuspicionLevelFatal, fmt.Sprintf("no route to host: %v", dst))
}
return nil, &assertions.CannotBuildTransmissionError{
SrcNode: p.netNode,
Err: fmt.Errorf("no route to host: %v", err)}
}
neigh, err := p.podInfo.NetNS.Neighbour.ProbeRouteNeigh(dstRoute, pkt.Dst)
if err != nil {
return nil, &assertions.CannotBuildTransmissionError{
SrcNode: p.netNode,
Err: fmt.Errorf("pod neigh system probe failed: %v", err),
}
}
if neigh != nil && (neigh.State == netstack.NudFailed || neigh.State == netstack.NudIncomplete) {
if dstRoute.Gw == nil {
p.netNode.AddSuspicion(model.SuspicionLevelCritical, fmt.Sprintf("dst: %v ARP resolve failed.", pkt.Dst.String()))
} else {
p.netNode.AddSuspicion(model.SuspicionLevelCritical, fmt.Sprintf("dst: %v route's gateway: %v ARP resolve failed.", pkt.Dst.String(), dstRoute.Gw.String()))
}
}
pkt.Src = net.ParseIP(addr)
iface, _ := lo.Find(p.podInfo.NetNS.Interfaces, func(i netstack.Interface) bool { return i.Name == "eth0" })
link := &model.Link{
Type: model.LinkVeth,
Source: p.netNode,
Packet: pkt,
SourceAttribute: model.VEthLinkAttribute{
SimpleLinkAttribute: model.SimpleLinkAttribute{
Interface: "eth0",
IP: addr,
},
PeerIndex: iface.PeerIndex,
},
}
err = p.net.AssertRoute(assertions.RouteAssertion{Dev: utils.ToPointer("eth0")}, *pkt, "", "")
if err != nil {
return nil, err
}
p.netNode.DoAction(model.ActionSend([]*model.Link{link}))
return []model.Transmission{
{
NextHop: model.Hop{
Type: model.NetNodeTypeNode,
ID: p.podInfo.NodeName,
},
Link: link,
},
}, nil
}