-
Notifications
You must be signed in to change notification settings - Fork 181
Expand file tree
/
Copy pathnetmonitor.go
More file actions
286 lines (257 loc) · 9.96 KB
/
netmonitor.go
File metadata and controls
286 lines (257 loc) · 9.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
// Copyright (c) 2022 Zededa, Inc.
// SPDX-License-Identifier: Apache-2.0
package netmonitor
import (
"context"
"net"
"github.com/lf-edge/eve/pkg/pillar/types"
"github.com/lf-edge/eve/pkg/pillar/utils/netutils"
)
// NetworkMonitor should allow to:
// - list (and possibly cache) network interfaces
// - obtain (and possibly cache) interface index
// - obtain (and possibly cache) interface attributes, addresses, DNS info, etc.
// - allow to watch for interface/address/route changes
// There should be one implementation for every supported network stack.
// NetworkMonitor should be thread-safe.
type NetworkMonitor interface {
// ListInterfaces returns all available network interfaces.
ListInterfaces() (ifNames []string, err error)
// GetInterfaceIndex : get interface index. Both name and index are unique
// interface identifiers, but while name is usually used in user-facing
// contexts, index is preferred in APIs (may vary between different network stacks).
// At least within NetworkMonitor, index is the preferred identifier and can be used
// with the methods below to obtain interface attributes, assigned addresses, etc.
// Do not keep the index for too long however, the mapping between the name and
// the index may change as interfaces are added/deleted.
GetInterfaceIndex(ifName string) (ifIndex int, exists bool, err error)
// GetInterfaceAttrs : get interface attributes (not including assigned addresses).
GetInterfaceAttrs(ifIndex int) (IfAttrs, error)
// GetInterfaceAddrs : get MAC address and a list of IP addresses assigned
// to the given interface.
GetInterfaceAddrs(ifIndex int) ([]*net.IPNet, net.HardwareAddr, error)
// GetInterfaceDNSInfo : get DNS information associated with the given interface.
// Function returns one entry for every resolv.conf file generated for the interface.
GetInterfaceDNSInfo(ifIndex int) ([]DNSInfo, error)
// GetInterfaceDHCPInfo : get DHCP + DHCPv6 information associated with the given interface.
// This information should be retrieved from the DHCP(v6) client.
GetInterfaceDHCPInfo(ifIndex int) (DHCPInfo, error)
// GetInterfaceDefaultGWs : return a list of IP addresses of default gateways
// used by the given interface. Includes both statically configured GWs as well as
// those assigned by DHCP.
// Returns both IPv4 and IPv6 gateways.
GetInterfaceDefaultGWs(ifIndex int) ([]net.IP, error)
// ListRoutes returns routes currently present in the routing tables.
// The set of routes to list can be filtered.
// Returns both IPv4 and IPv6 routes.
ListRoutes(filters RouteFilters) ([]Route, error)
// GetPNACStatus returns the current PNAC (Port Network Access Control) status
// for the specified interface.
// The exact 802.1x supplicant state and any associated error condition are obtained
// by querying `wpa_cli status`. The per-interface PNAC state file (see PNACStateDir)
// is used only to determine the timestamp of the last successful 802.1X authentication.
GetPNACStatus(ifIndex int) (types.PNACStatus, error)
// GetPNACMetrics returns IEEE 802.1X PNAC (Port-Based Network Access Control)
// metrics for the specified interface.
GetPNACMetrics(ifIndex int) (types.PNACMetrics, error)
// GetBondStatus : retrieve runtime status of a bond interface.
// Returns an error if the interface is not a bond or does not exist.
GetBondStatus(ifIndex int) (BondStatus, error)
// GetBondMetrics : retrieve metrics for a bond interface and its members.
// Returns an error if the interface is not a bond or does not exist.
// Note: BondMetrics.LogicalLabel and BondMemberMetrics.LogicalLabel are
// returned unset (NetworkMonitor does not work with logical labels).
GetBondMetrics(ifIndex int) (types.BondMetrics, error)
// ClearCache : clear cached mappings between interface names, interface indexes,
// attributes, assigned addresses, DNS info, DHCP info and default GWs.
// It is reasonable to do this once in a while because the monitor can miss some
// notification from the network stack and therefore the cache can get out-of-date
// over time.
ClearCache()
// WatchEvents : subscribe to watch for changes happening inside the network stack
// related to interfaces, routes, DNS, etc.
// The returned channel should be reasonably buffered.
WatchEvents(ctx context.Context, subName string) <-chan Event
}
// Event received from the network stack.
type Event interface {
isNetworkEvent()
}
// Route : IP route.
type Route struct {
IfIndex int
Dst *net.IPNet
Gw net.IP
Table int
// Network-stack specific data.
Data interface{}
}
// IsDefaultRoute returns true if this is a default route, i.e. matches all destinations.
func (r Route) IsDefaultRoute() bool {
if r.Dst == nil {
return true
}
ones, _ := r.Dst.Mask.Size()
return r.Dst.IP.IsUnspecified() && ones == 0
}
// RouteChange : a route was added or removed.
type RouteChange struct {
Route
Added bool
Deleted bool
}
// RouteFilters : used by ListRoutes() to limit the set of routes to list.
type RouteFilters struct {
// Enable to retrieve routes only from the given table.
FilterByTable bool
Table int
// Enable to retrieve only those routes which are associated
// with the given interface.
FilterByIf bool
IfIndex int
}
func (e RouteChange) isNetworkEvent() {}
// AddrChange : IP address was (un)assigned from/to interface.
type AddrChange struct {
IfIndex int
IfAddress *net.IPNet
Deleted bool
}
func (e AddrChange) isNetworkEvent() {}
// IfChange : interface (dis)appeared or attributes changed.
type IfChange struct {
Attrs IfAttrs
// True if this is a newly added interface.
Added bool
// True if interface was removed.
Deleted bool
}
func (e IfChange) isNetworkEvent() {}
// Equal allows to compare two IfChange events for equality.
func (e IfChange) Equal(e2 IfChange) bool {
return e.Added == e2.Added &&
e.Deleted == e2.Deleted &&
e.Attrs.Equal(e2.Attrs)
}
// DNSInfoChange : DNS information for interface has changed.
type DNSInfoChange struct {
IfIndex int
Info []DNSInfo
}
func (e DNSInfoChange) isNetworkEvent() {}
// IfAttrs : interface attributes.
type IfAttrs struct {
// Index of the interface
IfIndex int
// Name of the interface.
IfName string
// IfType should be one of the link types as defined in ip-link(8).
IfType string
// True if interface is a loopback interface.
IsLoopback bool
// True if interface supports broadcast access capability.
WithBroadcast bool
// True if interface is administratively enabled.
AdminUp bool
// True if interface is ready to transmit data at the L1 layer.
LowerUp bool
// True if interface is a slave of another interface (e.g. a sub-interface).
Enslaved bool
// If interface is enslaved, this should contain index of the master interface.
MasterIfIndex int
// Maximum Transmission Unit configured on the interface.
MTU uint16
// Index of the VLAN parent interface (only set for VLAN sub-interfaces).
VlanParentIfIndex int
// VLAN ID assigned to this subinterface (only set for VLAN sub-interfaces).
VlanID uint16
}
// Equal allows to compare two sets of interface attributes for equality.
func (a IfAttrs) Equal(a2 IfAttrs) bool {
return a.IfIndex == a2.IfIndex &&
a.IfName == a2.IfName &&
a.IfType == a2.IfType &&
a.IsLoopback == a2.IsLoopback &&
a.WithBroadcast == a2.WithBroadcast &&
a.AdminUp == a2.AdminUp &&
a.LowerUp == a2.LowerUp &&
a.Enslaved == a2.Enslaved &&
a.MasterIfIndex == a2.MasterIfIndex &&
a.MTU == a2.MTU &&
a.VlanParentIfIndex == a2.VlanParentIfIndex &&
a.VlanID == a2.VlanID
}
// DNSInfo : DNS information associated with an interface.
type DNSInfo struct {
ResolvConfPath string
Domains []string
DNSServers []net.IP
ForIPv6 bool
}
// DHCPInfo : DHCP information associated with an interface.
type DHCPInfo struct {
IPv4Subnet *net.IPNet
IPv6Subnets []*net.IPNet
IPv4NtpServers []netutils.HostnameOrIP
IPv6NtpServers []netutils.HostnameOrIP
}
// PNACEvent represents a change in port authentication state.
// Only reports transitions between non-authenticated and fully authenticated.
// Does not capture intermediate EAP states; intended to trigger network
// configuration changes that depend on port auth (e.g., acquiring (new) DHCP lease).
type PNACEvent struct {
IfName string
IsAuthenticated bool
}
func (e PNACEvent) isNetworkEvent() {}
// BondStatus : runtime status of a bond interface as reported by the kernel.
type BondStatus struct {
// Mode is the bonding mode as reported by the kernel.
Mode types.BondMode
// ActiveMemberIfIndex is the ifindex of the currently active member.
// Applicable for active-backup, balance-tlb and balance-alb modes.
// Zero if there is no active member.
ActiveMemberIfIndex int
// Monitoring parameters.
Miimon uint32
UpDelay uint32
DownDelay uint32
ArpInterval uint32
ArpIPTargets []net.IP
PeerNotificationDelay uint32
ArpMissedMax uint32
// LACPInfo contains 802.3ad aggregator info.
// Only set when bond mode is 802.3ad.
LACPInfo *BondLACPInfo
// Members contains per-member status.
Members []BondMemberStatus
}
// BondMemberStatus : per-member status within a bond.
type BondMemberStatus struct {
// IfIndex of the member interface.
IfIndex int
// MIIUp indicates whether the member's MII link is up.
MIIUp bool
// AggregatorID the member belongs to (802.3ad only).
AggregatorID uint16
// ActorChurnState (802.3ad only).
ActorChurnState types.BondLACPChurnState
// PartnerChurnState (802.3ad only).
PartnerChurnState types.BondLACPChurnState
}
// BondLACPInfo : 802.3ad aggregator info for a bond.
type BondLACPInfo struct {
AggregatorID uint16
ActorKey uint16
PartnerKey uint16
PartnerMAC net.HardwareAddr
}
// BondActiveMemberChange : the active member of a bond has changed.
type BondActiveMemberChange struct {
// BondIfIndex is the ifindex of the bond master interface.
BondIfIndex int
// ActiveMemberIfIndex is the ifindex of the new active member.
// Zero if there is no active member.
ActiveMemberIfIndex int
}
func (e BondActiveMemberChange) isNetworkEvent() {}