Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

weaveworks / weave / #7201

20 Sep 2016 - 16:03 coverage decreased (-0.1%) to 73.98%
#7201

Pull #2501

circleci

7de8841b37903eead0e0bb4d567e9454?size=18&default=identiconbrb
Update weaveworks/mesh submodule
Pull Request #2501: Reject empty peers

6616 of 8943 relevant lines covered (73.98%)

121129.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.97
/common/utils.go
1
package common
2

3
import (
4
        "fmt"
5
        "net"
6
        "os"
7
        "strings"
8

9
        "github.com/j-keck/arping"
10
        "github.com/vishvananda/netlink"
11
        "github.com/vishvananda/netns"
12

13
        weavenet "github.com/weaveworks/weave/net"
14
)
15

16
// Assert test is true, panic otherwise
17
func Assert(test bool) {
3,946,428×
18
        if !test {
3,946,429×
19
                panic("Assertion failure")
1×
20
        }
21
}
22

23
func ErrorMessages(errors []error) string {
!
24
        var result []string
!
25
        for _, err := range errors {
!
26
                result = append(result, err.Error())
!
27
        }
!
28
        return strings.Join(result, "\n")
!
29
}
30

31
type NetDev struct {
32
        Name  string
33
        MAC   net.HardwareAddr
34
        CIDRs []*net.IPNet
35
}
36

37
// Search the network namespace of a process for interfaces matching a predicate
38
// Note that the predicate is called while the goroutine is inside the process' netns
39
func FindNetDevs(processID int, match func(link netlink.Link) bool) ([]NetDev, error) {
9×
40
        var netDevs []NetDev
9×
41

9×
42
        ns, err := netns.GetFromPid(processID)
9×
43
        if err != nil {
9×
44
                if os.IsNotExist(err) {
!
45
                        return nil, nil
!
46
                }
!
47
                return nil, err
!
48
        }
49
        defer ns.Close()
9×
50

9×
51
        err = weavenet.WithNetNSUnsafe(ns, func() error {
18×
52
                return forEachLink(func(link netlink.Link) error {
36×
53
                        if match(link) {
28×
54
                                netDev, err := linkToNetDev(link)
1×
55
                                if err != nil {
1×
56
                                        return err
!
57
                                }
!
58
                                netDevs = append(netDevs, netDev)
1×
59
                        }
60
                        return nil
27×
61
                })
62
        })
63

64
        return netDevs, err
9×
65
}
66

67
func forEachLink(f func(netlink.Link) error) error {
10×
68
        links, err := netlink.LinkList()
10×
69
        if err != nil {
10×
70
                return err
!
71
        }
!
72
        for _, link := range links {
47×
73
                if err := f(link); err != nil {
37×
74
                        return err
!
75
                }
!
76
        }
77
        return nil
10×
78
}
79

80
func linkToNetDev(link netlink.Link) (NetDev, error) {
73×
81
        addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
73×
82
        if err != nil {
73×
83
                return NetDev{}, err
!
84
        }
!
85

86
        netDev := NetDev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr}
73×
87
        for _, addr := range addrs {
146×
88
                netDev.CIDRs = append(netDev.CIDRs, addr.IPNet)
73×
89
        }
73×
90
        return netDev, nil
73×
91
}
92

93
// ConnectedToBridgePredicate returns a function which is used to query whether
94
// a given link is a veth interface which one end is connected to a bridge.
95
// The returned function should be called from a container network namespace which
96
// the bridge does NOT belong to.
97
func ConnectedToBridgePredicate(bridgeName string) (func(link netlink.Link) bool, error) {
1×
98
        indexes := make(map[int]struct{})
1×
99

1×
100
        // Scan devices in root namespace to find those attached to weave bridge
1×
101
        err := weavenet.WithNetNSLinkByPidUnsafe(1, bridgeName,
1×
102
                func(br netlink.Link) error {
2×
103
                        return forEachLink(func(link netlink.Link) error {
11×
104
                                if link.Attrs().MasterIndex == br.Attrs().Index {
12×
105
                                        peerIndex := link.Attrs().ParentIndex
2×
106
                                        if peerIndex == 0 {
4×
107
                                                // perhaps running on an older kernel where ParentIndex doesn't work.
2×
108
                                                // as fall-back, assume the indexes are consecutive
2×
109
                                                peerIndex = link.Attrs().Index - 1
2×
110
                                        }
2×
111
                                        indexes[peerIndex] = struct{}{}
2×
112
                                }
113
                                return nil
10×
114
                        })
115
                })
116
        if err != nil {
1×
117
                return nil, err
!
118
        }
!
119

120
        return func(link netlink.Link) bool {
4×
121
                _, isveth := link.(*netlink.Veth)
3×
122
                _, found := indexes[link.Attrs().Index]
3×
123
                return isveth && found
3×
124
        }, nil
3×
125
}
126

127
func GetNetDevsWithPredicate(processID int, predicate func(link netlink.Link) bool) ([]NetDev, error) {
1×
128
        // Bail out if this container is running in the root namespace
1×
129
        nsToplevel, err := netns.GetFromPid(1)
1×
130
        if err != nil {
1×
131
                return nil, fmt.Errorf("unable to open root namespace: %s", err)
!
132
        }
!
133
        nsContainr, err := netns.GetFromPid(processID)
1×
134
        if err != nil {
1×
UNCOV
135
                return nil, fmt.Errorf("unable to open process %d namespace: %s", processID, err)
!
136
        }
!
137
        if nsToplevel.Equal(nsContainr) {
1×
138
                return nil, nil
!
139
        }
!
140

141
        return FindNetDevs(processID, predicate)
1×
142
}
143

144
// Lookup the weave interface of a container
145
func GetWeaveNetDevs(processID int) ([]NetDev, error) {
1×
146
        p, err := ConnectedToBridgePredicate("weave")
1×
147
        if err != nil {
1×
UNCOV
148
                return nil, err
!
UNCOV
149
        }
!
150

151
        return GetNetDevsWithPredicate(processID, p)
1×
152
}
153

154
// Get the weave bridge interface.
155
// NB: Should be called from the root network namespace.
156
func GetBridgeNetDev(bridgeName string) (NetDev, error) {
72×
157
        link, err := netlink.LinkByName(bridgeName)
72×
158
        if err != nil {
72×
UNCOV
159
                return NetDev{}, err
!
UNCOV
160
        }
!
161

162
        return linkToNetDev(link)
72×
163
}
164

165
// Do post-attach configuration of all veths we have created
166
func ConfigureARPforVeths(processID int, prefix string) error {
8×
167
        _, err := FindNetDevs(processID, func(link netlink.Link) bool {
32×
168
                ifName := link.Attrs().Name
24×
169
                if strings.HasPrefix(ifName, prefix) {
32×
170
                        weavenet.ConfigureARPCache(ifName)
8×
171
                        if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil {
16×
172
                                for _, addr := range addrs {
16×
173
                                        arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName)
8×
174
                                }
8×
175
                        }
176
                }
177
                return false
24×
178
        })
179
        return err
8×
180
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2022 Coveralls, Inc