Skip to content

Commit 285eb25

Browse files
authored
NETOBSERV-1732: add logic to lkup all previous tc filters and remove them (#360)
Signed-off-by: Mohamed Mahmoud <[email protected]>
1 parent 512b870 commit 285eb25

File tree

1 file changed

+88
-2
lines changed

1 file changed

+88
-2
lines changed

pkg/ebpf/tracer.go

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/vishvananda/netlink"
2424
"github.com/vishvananda/netns"
2525
"golang.org/x/sys/unix"
26+
kerrors "k8s.io/apimachinery/pkg/util/errors"
2627
)
2728

2829
// $BPF_CLANG and $BPF_CFLAGS are set by the Makefile.
@@ -42,6 +43,8 @@ const (
4243
pktDropHook = "kfree_skb"
4344
constPcaEnable = "enable_pca"
4445
pcaRecordsMap = "packet_record"
46+
tcEgressFilterName = "tc/tc_egress_flow_parse"
47+
tcIngressFilterName = "tc/tc_ingress_flow_parse"
4548
)
4649

4750
var log = logrus.WithField("component", "ebpf.FlowFetcher")
@@ -249,6 +252,84 @@ func (m *FlowFetcher) AttachTCX(iface ifaces.Interface) error {
249252
return nil
250253
}
251254

255+
func removeTCFilters(ifName string, tcDir uint32) error {
256+
link, err := netlink.LinkByName(ifName)
257+
if err != nil {
258+
return err
259+
}
260+
261+
filters, err := netlink.FilterList(link, tcDir)
262+
if err != nil {
263+
return err
264+
}
265+
var errs []error
266+
for _, f := range filters {
267+
if err := netlink.FilterDel(f); err != nil {
268+
errs = append(errs, err)
269+
}
270+
}
271+
272+
return kerrors.NewAggregate(errs)
273+
}
274+
275+
func (m *FlowFetcher) removePreviousFilters(iface ifaces.Interface) error {
276+
ilog := log.WithField("iface", iface)
277+
ilog.Debugf("looking for previously installed TC filters on %s", iface.Name)
278+
links, err := netlink.LinkList()
279+
if err != nil {
280+
return fmt.Errorf("retrieving all netlink devices: %w", err)
281+
}
282+
283+
egressDevs := []netlink.Link{}
284+
ingressDevs := []netlink.Link{}
285+
for _, l := range links {
286+
if l.Attrs().Name != iface.Name {
287+
continue
288+
}
289+
ingressFilters, err := netlink.FilterList(l, netlink.HANDLE_MIN_INGRESS)
290+
if err != nil {
291+
return fmt.Errorf("listing ingress filters: %w", err)
292+
}
293+
for _, filter := range ingressFilters {
294+
if bpfFilter, ok := filter.(*netlink.BpfFilter); ok {
295+
if strings.HasPrefix(bpfFilter.Name, tcIngressFilterName) {
296+
ingressDevs = append(ingressDevs, l)
297+
}
298+
}
299+
}
300+
301+
egressFilters, err := netlink.FilterList(l, netlink.HANDLE_MIN_EGRESS)
302+
if err != nil {
303+
return fmt.Errorf("listing egress filters: %w", err)
304+
}
305+
for _, filter := range egressFilters {
306+
if bpfFilter, ok := filter.(*netlink.BpfFilter); ok {
307+
if strings.HasPrefix(bpfFilter.Name, tcEgressFilterName) {
308+
egressDevs = append(egressDevs, l)
309+
}
310+
}
311+
}
312+
}
313+
314+
for _, dev := range ingressDevs {
315+
ilog.Debugf("removing ingress stale tc filters from %s", dev.Attrs().Name)
316+
err = removeTCFilters(dev.Attrs().Name, netlink.HANDLE_MIN_INGRESS)
317+
if err != nil {
318+
ilog.WithError(err).Errorf("couldn't remove ingress tc filters from %s", dev.Attrs().Name)
319+
}
320+
}
321+
322+
for _, dev := range egressDevs {
323+
ilog.Debugf("removing egress stale tc filters from %s", dev.Attrs().Name)
324+
err = removeTCFilters(dev.Attrs().Name, netlink.HANDLE_MIN_EGRESS)
325+
if err != nil {
326+
ilog.WithError(err).Errorf("couldn't remove egress tc filters from %s", dev.Attrs().Name)
327+
}
328+
}
329+
330+
return nil
331+
}
332+
252333
// Register and links the eBPF fetcher into the system. The program should invoke Unregister
253334
// before exiting.
254335
func (m *FlowFetcher) Register(iface ifaces.Interface) error {
@@ -285,6 +366,11 @@ func (m *FlowFetcher) Register(iface ifaces.Interface) error {
285366
}
286367
m.qdiscs[iface] = qdisc
287368

369+
// Remove previously installed filters
370+
if err := m.removePreviousFilters(iface); err != nil {
371+
return fmt.Errorf("failed to remove previous filters: %w", err)
372+
}
373+
288374
if err := m.registerEgress(iface, ipvlan, handle); err != nil {
289375
return err
290376
}
@@ -309,7 +395,7 @@ func (m *FlowFetcher) registerEgress(iface ifaces.Interface, ipvlan netlink.Link
309395
egressFilter := &netlink.BpfFilter{
310396
FilterAttrs: egressAttrs,
311397
Fd: m.objects.TcEgressFlowParse.FD(),
312-
Name: "tc/tc_egress_flow_parse",
398+
Name: tcEgressFilterName,
313399
DirectAction: true,
314400
}
315401
if err := handle.FilterDel(egressFilter); err == nil {
@@ -343,7 +429,7 @@ func (m *FlowFetcher) registerIngress(iface ifaces.Interface, ipvlan netlink.Lin
343429
ingressFilter := &netlink.BpfFilter{
344430
FilterAttrs: ingressAttrs,
345431
Fd: m.objects.TcIngressFlowParse.FD(),
346-
Name: "tc/tc_ingress_flow_parse",
432+
Name: tcIngressFilterName,
347433
DirectAction: true,
348434
}
349435
if err := handle.FilterDel(ingressFilter); err == nil {

0 commit comments

Comments
 (0)