Skip to content

Commit

Permalink
Merge pull request #8707 from tomastigera/tomas-bpf-dual-stack-for-v6…
Browse files Browse the repository at this point in the history
…-only

[BPF] dual stack for v6 only
  • Loading branch information
tomastigera committed Apr 11, 2024
2 parents e817dae + ee729dd commit e678649
Show file tree
Hide file tree
Showing 4 changed files with 370 additions and 170 deletions.
23 changes: 20 additions & 3 deletions felix/bpf-gpl/tc_preamble.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,36 @@ SEC("tc")
int cali_tc_preamble(struct __sk_buff *skb)
{
volatile struct cali_tc_globals *globals = state_get_globals_tc();
const volatile struct cali_tc_global_data *globals_data = NULL;

if (!globals) {
return TC_ACT_SHOT;
}

__u16 protocol = bpf_ntohs(skb->protocol);
/* Set the globals for the rest of the prog chain. */
if (protocol == ETH_P_IPV6 && (__globals.v6.jumps[PROG_INDEX_MAIN] != (__u32)-1)) {
globals->data = __globals.v6;
if (protocol == ETH_P_IPV6) {
if (__globals.v6.jumps[PROG_INDEX_MAIN] != (__u32)-1) {
globals_data = &__globals.v6;
} else if (__globals.v4.jumps[PROG_INDEX_MAIN] != (__u32)-1) {
globals_data = &__globals.v4;
}
} else {
globals->data = __globals.v4;
if (__globals.v4.jumps[PROG_INDEX_MAIN] != (__u32)-1) {
globals_data = &__globals.v4;
} else if (__globals.v6.jumps[PROG_INDEX_MAIN] != (__u32)-1) {
globals_data = &__globals.v6;
}
}

if (!globals_data) {
CALI_LOG("Main program not loaded for IP packet version %d, DROP\n", protocol);
return TC_ACT_SHOT;
}

/* We do the copy once here so keep the program smaller */
globals->data = *globals_data;

#if EMIT_LOGS
CALI_LOG("tc_preamble iface %s\n", globals->data.iface_name);
#endif
Expand Down
88 changes: 72 additions & 16 deletions felix/dataplane/linux/bpf_ep_mgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -908,13 +908,7 @@ func (m *bpfEndpointManager) reclaimPolicyIdx(name string, ipFamily int, iface *
}
if attachHook != hook.XDP {
if err := m.jumpMapAlloc.Put(idx.policyIdx[attachHook], name); err != nil {
log.WithError(err).Error(attachHook.String())
}
if err := m.jumpMapDelete(attachHook, iface.dpState.filterIdx[attachHook]); err != nil {
log.WithError(err).Warn("Filter program may leak.")
}
if err := m.jumpMapAlloc.Put(iface.dpState.filterIdx[attachHook], name); err != nil {
log.WithError(err).Error(attachHook.String())
log.WithError(err).Errorf("Policy family %d, hook %s", ipFamily, attachHook)
}
} else {
if err := m.xdpJumpMapAlloc.Put(idx.policyIdx[attachHook], name); err != nil {
Expand All @@ -924,6 +918,17 @@ func (m *bpfEndpointManager) reclaimPolicyIdx(name string, ipFamily int, iface *
}
}

func (m *bpfEndpointManager) reclaimFilterIdx(name string, iface *bpfInterface) {
for _, attachHook := range []hook.Hook{hook.Ingress, hook.Egress} {
if err := m.jumpMapDelete(attachHook, iface.dpState.filterIdx[attachHook]); err != nil {
log.WithError(err).Warn("Filter program may leak.")
}
if err := m.jumpMapAlloc.Put(iface.dpState.filterIdx[attachHook], name); err != nil {
log.WithError(err).Errorf("Filter hook %s", attachHook)
}
}
}

func (m *bpfEndpointManager) updateIfaceStateMap(name string, iface *bpfInterface) {
k := ifstate.NewKey(uint32(iface.info.ifIndex))
if iface.info.ifaceIsUp() {
Expand Down Expand Up @@ -955,6 +960,7 @@ func (m *bpfEndpointManager) updateIfaceStateMap(name string, iface *bpfInterfac
if m.v6 != nil {
m.reclaimPolicyIdx(name, 6, iface)
}
m.reclaimFilterIdx(name, iface)
m.ifStateMap.Desired().Delete(k)
iface.dpState.clearJumps()
}
Expand Down Expand Up @@ -1568,7 +1574,7 @@ func (m *bpfEndpointManager) CompleteDeferredWork() error {
m.reportHealth(true, "")
} else {
m.dirtyIfaceNames.Iter(func(iface string) error {
m.updateRateLimitedLog.WithField("name", iface).Debug("Interface remains dirty.")
m.updateRateLimitedLog.WithField("name", iface).Info("Interface remains dirty.")
return nil
})
m.reportHealth(false, "Failed to configure some interfaces.")
Expand Down Expand Up @@ -1692,12 +1698,35 @@ func (m *bpfEndpointManager) doApplyPolicyToDataIface(iface string) (bpfInterfac
return state, xdpErr
}

if m.v6 != nil && err6 == nil {
state.v6Readiness = ifaceIsReady
if err4 != nil && err6 != nil {
// This covers the case when we don't have hostIP on both paths.
return state, errors.Join(err4, err6)
}

if m.v6 != nil {
if err6 == nil {
state.v6Readiness = ifaceIsReady
}
if m.v6.hostIP == nil {
// If we do not have host IP for the IP version, we certainly error.
// But that should not prevent the other IP version path from
// working correctly.
err6 = nil
}
}
if m.v4 != nil && err4 == nil {
state.v4Readiness = ifaceIsReady

if m.v4 != nil {
if err4 == nil {
state.v4Readiness = ifaceIsReady
}
if m.v4.hostIP == nil {
// If we do not have host IP for the IP version, we certainly error.
// But that should not prevent the other IP version path from
// working correctly.
err4 = nil
}
}

return state, errors.Join(err4, err6)
}

Expand All @@ -1709,6 +1738,11 @@ func (m *bpfEndpointManager) applyProgramsToDirtyDataInterfaces() {
if !m.isDataIface(iface) && !m.isL3Iface(iface) {
log.WithField("iface", iface).Debug(
"Ignoring interface that doesn't match the host data/l3 interface regex")
if !m.isWorkloadIface(iface) {
log.WithField("iface", iface).Debug(
"Removing interface that doesn't match the host data/l3 interface and is not workload interface")
return set.RemoveItem
}
return nil
}

Expand Down Expand Up @@ -2106,11 +2140,33 @@ func (m *bpfEndpointManager) doApplyPolicy(ifaceName string) (bpfInterfaceState,
}
state.qdisc = ingressQdisc

if m.v6 != nil && err6 == nil {
state.v6Readiness = ifaceIsReady
if err4 != nil && err6 != nil {
// This covers the case when we don't have hostIP on both paths.
return state, errors.Join(err4, err6)
}

if m.v6 != nil {
if err6 == nil {
state.v6Readiness = ifaceIsReady
}
if m.v6.hostIP == nil {
// If we do not have host IP for the IP version, we certainly error.
// But that should not prevent the other IP version path from
// working correctly.
err6 = nil
}
}
if m.v4 != nil && err4 == nil {
state.v4Readiness = ifaceIsReady

if m.v4 != nil {
if err4 == nil {
state.v4Readiness = ifaceIsReady
}
if m.v4.hostIP == nil {
// If we do not have host IP for the IP version, we certainly error.
// But that should not prevent the other IP version path from
// working correctly.
err4 = nil
}
}

if errors.Join(err4, err6) != nil {
Expand Down
Loading

0 comments on commit e678649

Please sign in to comment.