Skip to content

Commit 98b4898

Browse files
committed
fix: duplicated nodename causing invalid dot output
1 parent 8806f00 commit 98b4898

File tree

7 files changed

+195
-146
lines changed

7 files changed

+195
-146
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build:
2+
CGO_ENABLED=1 go build --ldflags '-extldflags "-static"' -o iftree cmd/iftree/main.go
3+

cmd/iftree/main.go

Lines changed: 52 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ import (
1111
"syscall"
1212

1313
"github.com/containerd/nerdctl/pkg/rootlessutil"
14-
log "github.com/sirupsen/logrus"
14+
"github.com/pkg/errors"
15+
"github.com/sirupsen/logrus"
1516
"github.com/spf13/pflag"
1617
"github.com/vishvananda/netlink"
1718
"github.com/vishvananda/netns"
1819

19-
"github.com/t1anz0ng/iftree/pkg"
2020
"github.com/t1anz0ng/iftree/pkg/formatter"
2121
"github.com/t1anz0ng/iftree/pkg/netutil"
22+
"github.com/t1anz0ng/iftree/pkg/types"
2223
)
2324

2425
var (
@@ -63,6 +64,7 @@ Help Options:
6364
version: %s
6465
`, version)
6566
}
67+
6668
}
6769

6870
func helper() error {
@@ -75,77 +77,82 @@ func helper() error {
7577
}
7678
return nil
7779
}
80+
7881
func main() {
7982
pflag.Parse()
8083
if err := helper(); err != nil {
81-
log.Fatal(err)
84+
logrus.Fatal(err)
8285
}
8386
if rootlessutil.IsRootless() {
84-
log.Error("iftree must be run as root to enter ns")
87+
logrus.Error("iftree must be run as root to enter ns")
8588
os.Exit(1)
8689
}
87-
log.SetLevel(log.InfoLevel)
90+
logrus.SetLevel(logrus.InfoLevel)
8891
if *debug {
89-
log.SetReportCaller(true)
90-
log.SetLevel(log.DebugLevel)
92+
logrus.SetReportCaller(true)
93+
logrus.SetLevel(logrus.DebugLevel)
94+
} else {
95+
logrus.SetLevel(logrus.ErrorLevel)
9196
}
97+
98+
// Lock the OS Thread so we don't accidentally switch namespaces
9299
runtime.LockOSThread()
93100
defer runtime.UnlockOSThread()
94101

95102
netNsMap, err := netutil.NetNsMap()
96103
if err != nil {
97-
log.Fatal(err)
104+
logrus.Fatal(err)
98105
}
99106
if len(netNsMap) == 0 {
100-
log.Warn("no netns found")
107+
logrus.Warn("no netns found")
101108
os.Exit(0)
102109
}
103-
log.Debugf("net namespace id <-> name map:\n%+v\n", netNsMap)
110+
logrus.Debugf("net namespace id <-> name map:\n%+v\n", netNsMap)
104111

105112
ll, err := netlink.LinkList()
106113
if err != nil {
107-
log.Fatal(err)
114+
logrus.Fatal(errors.Unwrap(err))
108115
}
109-
log.Debugf("net link list:\n%+v\n", ll)
116+
logrus.Debugf("net link list:\n%+v\n", ll)
110117

111-
bridgeVethM := make(map[string][]pkg.Node) // map bridge <-> veth paris
112-
unBridgedVpairs := []pkg.Node{}
118+
bridgeVethM := make(map[string][]types.Node) // map bridge <-> veth paris
119+
unBridgedVpairs := []types.Node{}
113120
bridgeIps := make(map[string]*net.IP) // bridge ip
114-
loS := []pkg.Node{} // loopback
121+
loS := []types.Node{} // loopback
115122

116123
origin, err := netns.Get()
117124
if err != nil {
118-
log.Fatalf("failed get current netne, %v", err)
125+
logrus.Fatalf("failed get current netne, %v", err)
119126
}
120-
// FIXME: use undirected graph insted of array/map to store relations
127+
121128
for _, link := range ll {
122129
veth, ok := link.(*netlink.Veth)
123130
if !ok {
124131
// skip device not enslaved to any bridge
125-
log.Debugf("skip %s, type: %s", link.Attrs().Name, link.Type())
132+
logrus.Debugf("skip %s, type: %s", link.Attrs().Name, link.Type())
126133
continue
127134
}
128-
log.Debugf("found veth device: %s", veth.Name)
135+
logrus.Debugf("veth device: %+v", veth)
129136

130137
peerIdx, err := netlink.VethPeerIndex(veth)
131138
if err != nil {
132-
log.Fatal(err)
139+
logrus.Fatal(err)
133140
}
134141
if link.Attrs().MasterIndex == -1 || veth.MasterIndex == 0 {
135-
log.Debugf("%s not has a bridge as master, MasterIndex: %d", veth.Name, link.Attrs().MasterIndex)
142+
logrus.Debugf("%s not has a bridge as master, MasterIndex: %d", veth.Name, link.Attrs().MasterIndex)
136143
if veth.PeerName == "" {
137144
p, err := netlink.LinkByIndex(peerIdx)
138145
if err != nil {
139-
log.Fatal(err)
146+
logrus.Fatal(err)
140147
}
141148
veth.PeerName = p.Attrs().Name
142149
}
143150
routes, err := netlink.RouteList(link, 4)
144151
if err != nil {
145-
log.Fatal(err)
152+
logrus.Fatal(err)
146153
}
147-
node := pkg.Node{
148-
Type: pkg.VethType,
154+
node := types.Node{
155+
Type: types.VethType,
149156
Veth: veth.Name,
150157
Peer: veth.PeerName,
151158
PeerId: peerIdx,
@@ -161,7 +168,7 @@ func main() {
161168

162169
master, err := netlink.LinkByIndex(veth.Attrs().MasterIndex)
163170
if err != nil {
164-
log.Fatal(err)
171+
logrus.Fatal(err)
165172
}
166173

167174
// if master is not bridge
@@ -172,27 +179,27 @@ func main() {
172179
bridge := master.Attrs().Name
173180
v, ok := bridgeVethM[bridge]
174181
if !ok {
175-
bridgeVethM[bridge] = []pkg.Node{}
182+
bridgeVethM[bridge] = []types.Node{}
176183
}
177-
pair := pkg.Node{
178-
Type: pkg.VethType,
184+
pair := types.Node{
185+
Type: types.VethType,
179186
Veth: veth.Name,
180187
PeerId: peerIdx,
181188
NetNsID: veth.NetNsID,
182189
}
183190
if peerNetNs, ok := netNsMap[veth.NetNsID]; ok {
184191
peerInNs, err := netutil.GetPeerInNs(peerNetNs, origin, peerIdx)
185192
if err != nil {
186-
log.Fatal(err)
193+
logrus.Fatal(err)
187194
}
188195
pair.NetNsName = peerNetNs
189196
pair.PeerNameInNetns = peerInNs.Attrs().Name
190197
pair.Status = peerInNs.Attrs().OperState.String()
191198

192199
lo, err := netutil.GetLoInNs(peerNetNs, origin)
193200
if err == nil && lo != nil {
194-
loS = append(loS, pkg.Node{
195-
Type: pkg.LoType,
201+
loS = append(loS, types.Node{
202+
Type: types.LoType,
196203
NetNsName: peerNetNs,
197204
Status: lo.Attrs().OperState.String(),
198205
})
@@ -203,25 +210,25 @@ func main() {
203210

204211
addrs, err := netlink.AddrList(master, syscall.AF_INET)
205212
if err != nil {
206-
log.Fatal(err)
213+
logrus.Fatal(err)
207214
}
208215
if len(addrs) > 0 {
209-
pair.Master = &pkg.Bridge{
216+
pair.Master = &types.Bridge{
210217
Name: bridge,
211218
IP: &addrs[0].IP,
212219
}
213220
bridgeIps[bridge] = &addrs[0].IP
214221
}
215222
bridgeVethM[bridge] = append(v, pair)
216223
}
217-
log.Debugf("bridgeVethMap: %+v", bridgeVethM)
224+
logrus.Debugf("bridgeVethMap: %+v", bridgeVethM)
218225

219226
switch {
220227
case *oGraph:
221228
buf := bytes.Buffer{}
222229
output, err := formatter.GraphInDOT(bridgeVethM, unBridgedVpairs, loS, bridgeIps)
223230
if err != nil {
224-
log.Fatal(err)
231+
logrus.Fatal(errors.Unwrap(err))
225232
}
226233
fmt.Fprintln(&buf, output)
227234
gType := strings.ToLower(*oGraphType)
@@ -231,21 +238,25 @@ func main() {
231238
_, err = io.Copy(defaultOutput, &buf)
232239
case "jpg", "png", "svg":
233240
if !pflag.CommandLine.Changed("output") && !pflag.CommandLine.Changed("gtype") {
234-
log.Warn(`default output dst file: "output.png"`)
241+
logrus.Warn(`default output dst file: "output.png"`)
242+
}
243+
if fn, err := formatter.GenImage(buf.Bytes(), oGraphName, gType); err != nil {
244+
os.Remove(fn)
245+
logrus.Fatal(errors.Unwrap(err))
235246
}
236-
err = formatter.GenImage(buf.Bytes(), oGraphName, gType)
237247
default:
238-
log.Fatal("invalid graph type")
248+
logrus.Error("unknown image type")
249+
os.Exit(1)
239250
}
240251
if err != nil {
241-
log.Fatal(err)
252+
logrus.Fatal(err)
242253
}
243254
return
244255
case *oTable:
245256
if len(bridgeVethM) > 0 {
246257
err := formatter.Table(defaultOutput, bridgeVethM)
247258
if err != nil {
248-
log.Fatal(err)
259+
logrus.Fatal(errors.Unwrap(err))
249260
}
250261
}
251262
if *oNotBridgedVeths && len(unBridgedVpairs) > 0 {

0 commit comments

Comments
 (0)