Skip to content

Commit f3ff09e

Browse files
tkatilapfl
authored andcommitted
discover: filter packets without correct syntax
Sometimes LLDP packets are sent with "default" port description field. This allows the listening to continue on malformed packets. Signed-off-by: Tuomas Katila <[email protected]>
1 parent b7ffe80 commit f3ff09e

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint-$(GOLANGCI_LINT_VERSION)
231231
KUSTOMIZE_VERSION ?= v5.3.0
232232
CONTROLLER_TOOLS_VERSION ?= v0.14.0
233233
ENVTEST_VERSION ?= release-0.17
234-
GOLANGCI_LINT_VERSION ?= v1.64.7
234+
GOLANGCI_LINT_VERSION ?= v1.64.8
235235

236236
.PHONY: kustomize
237237
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.

cmd/discover/main.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ func detectLLDP(config *cmdConfig, networkConfigs map[string]*networkConfigurati
9595
lldpResultChan := make(chan lldp.DiscoveryResult, len(networkConfigs))
9696
timeoutctx, cancelctx := context.WithTimeout(config.ctx, config.timeout)
9797

98+
filterFunc := func(portDescription string) bool {
99+
// Check if the port description field has the correct data in it
100+
_, _, err := parseIPFromString(portDescription)
101+
102+
return err == nil
103+
}
104+
98105
defer cancelctx()
99106

100107
for _, networkconfig := range networkConfigs {
@@ -107,7 +114,7 @@ func detectLLDP(config *cmdConfig, networkConfigs map[string]*networkConfigurati
107114
wg.Add(1)
108115
go func() {
109116
lldpClient := lldp.NewClient(timeoutctx, networkconfig.link.Attrs().Name, *networkconfig.localHwAddr)
110-
if err := lldpClient.Start(lldpResultChan); err != nil {
117+
if err := lldpClient.Start(lldpResultChan, filterFunc); err != nil {
111118
klog.Infof("Cannot start LLDP client: %v\n", err)
112119
}
113120
wg.Done()

cmd/discover/network.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,15 @@ func getNetworkConfigs(interfaces []string) ([]string, map[string]*networkConfig
213213
return allinterfaces, links, nil
214214
}
215215

216+
func parseIPFromString(portDescription string) (net.IP, *net.IPNet, error) {
217+
substrings := strings.Split(portDescription, " ")
218+
if len(substrings) < 2 {
219+
return nil, nil, fmt.Errorf("port description field doesn't follow expected format (no-alert CIDR)")
220+
}
221+
222+
return net.ParseCIDR(substrings[1])
223+
}
224+
216225
func selectMask30L3Address(nwconfig *networkConfiguration) (*net.IP, *net.IP, error) {
217226
var (
218227
peerNetwork *net.IPNet
@@ -221,15 +230,9 @@ func selectMask30L3Address(nwconfig *networkConfiguration) (*net.IP, *net.IP, er
221230
err error
222231
)
223232

224-
substrings := strings.Split(nwconfig.portDescription, " ")
225-
if len(substrings) < 2 {
226-
return nil, nil, fmt.Errorf("interface '%s' could not split string '%s'",
227-
nwconfig.link.Attrs().Name, nwconfig.portDescription)
228-
}
229-
230-
peeraddr, peerNetwork, err = net.ParseCIDR(substrings[1])
233+
peeraddr, peerNetwork, err = parseIPFromString(nwconfig.portDescription)
231234
if err != nil {
232-
return nil, nil, fmt.Errorf("interface '%s' could not parse '%s': %v",
235+
return nil, nil, fmt.Errorf("interface '%s' could not parse CIDR from port description '%s': %v",
233236
nwconfig.link.Attrs().Name, nwconfig.portDescription, err)
234237
}
235238

pkg/lldp/client.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func NewClient(ctx context.Context, ifacename string, hwAddr []byte) *Client {
7070
// Start searches on the configured interface for lldp packages and
7171
// pushes the optional TLV SysName and SysDescription fields of each
7272
// found lldp package into the given channel.
73-
func (l *Client) Start(resultChan chan<- DiscoveryResult) error {
73+
func (l *Client) Start(resultChan chan<- DiscoveryResult, portDescriptionFilter func(string) bool) error {
7474
defer l.Close()
7575

7676
var packetSource *gopacket.PacketSource
@@ -110,6 +110,8 @@ func (l *Client) Start(resultChan chan<- DiscoveryResult) error {
110110
continue
111111
}
112112

113+
infoFound := false
114+
113115
dr := DiscoveryResult{InterfaceName: l.InterfaceName}
114116
for _, layer := range packet.Layers() {
115117
if layer.LayerType() == layers.LayerTypeLinkLayerDiscovery {
@@ -134,12 +136,26 @@ func (l *Client) Start(resultChan chan<- DiscoveryResult) error {
134136
if !ok {
135137
continue
136138
}
139+
140+
if portDescriptionFilter != nil && !portDescriptionFilter(info.PortDescription) {
141+
// Filter function did not match, ignore this packet
142+
continue
143+
}
144+
137145
dr.SysName = info.SysName
138146
dr.SysDescription = info.SysDescription
139147
dr.PortDescription = info.PortDescription
148+
149+
infoFound = true
140150
}
141151

142152
}
153+
154+
if !infoFound {
155+
// We did not find the info layer, ignore this packet
156+
continue
157+
}
158+
143159
resultChan <- dr
144160
return nil
145161

0 commit comments

Comments
 (0)