Skip to content

Commit ee7f6f8

Browse files
committed
[BPF] move IP defrag to its own program
1 parent 4ee845a commit ee7f6f8

File tree

6 files changed

+75
-6
lines changed

6 files changed

+75
-6
lines changed

felix/bpf-gpl/jump.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ enum cali_jump_index {
6868
PROG_INDEX_HOST_CT_CONFLICT,
6969
PROG_INDEX_ICMP_INNER_NAT,
7070
PROG_INDEX_NEW_FLOW,
71+
PROG_INDEX_IP_FRAG,
7172

7273
PROG_INDEX_MAIN_DEBUG,
7374
PROG_INDEX_POLICY_DEBUG,
@@ -77,6 +78,7 @@ enum cali_jump_index {
7778
PROG_INDEX_HOST_CT_CONFLICT_DEBUG,
7879
PROG_INDEX_ICMP_INNER_NAT_DEBUG,
7980
PROG_INDEX_NEW_FLOW_DEBUG,
81+
PROG_INDEX_IP_FRAG_DEBUG,
8082
};
8183

8284
#if CALI_F_XDP

felix/bpf-gpl/tc.c

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,8 @@ int calico_tc_main(struct __sk_buff *skb)
204204

205205
#ifndef IPVER6
206206
if (CALI_F_TO_HOST && ip_is_frag(ip_hdr(ctx))) {
207-
if (!frags4_handle(ctx)) {
208-
deny_reason(ctx, CALI_REASON_FRAG_WAIT);
209-
goto deny;
210-
}
211-
/* force it through stack to trigger any further necessary fragmentation */
212-
ctx->state->flags |= CALI_ST_SKIP_REDIR_ONCE;
207+
CALI_JUMP_TO(ctx, PROG_INDEX_IP_FRAG);
208+
goto deny;
213209
}
214210
#endif
215211

@@ -2077,3 +2073,47 @@ int calico_tc_skb_drop(struct __sk_buff *skb)
20772073
CALI_DEBUG("DENY due to policy");
20782074
return TC_ACT_SHOT;
20792075
}
2076+
2077+
#ifndef IPVER6
2078+
SEC("tc")
2079+
int calico_tc_skb_ipv4_frag(struct __sk_buff *skb)
2080+
{
2081+
/* Initialise the context, which is stored on the stack, and the state, which
2082+
* we use to pass data from one program to the next via tail calls. */
2083+
DECLARE_TC_CTX(_ctx,
2084+
.skb = skb,
2085+
.fwd = {
2086+
.res = TC_ACT_UNSPEC,
2087+
.reason = CALI_REASON_UNKNOWN,
2088+
},
2089+
);
2090+
struct cali_tc_ctx *ctx = &_ctx;
2091+
2092+
CALI_DEBUG("Entering calico_tc_skb_ipv4_frag");
2093+
CALI_DEBUG("iphdr_offset %d ihl %d", skb_iphdr_offset(ctx), ctx->ipheader_len);
2094+
2095+
if (skb_refresh_validate_ptrs(ctx, UDP_SIZE)) {
2096+
deny_reason(ctx, CALI_REASON_SHORT);
2097+
CALI_DEBUG("Too short");
2098+
goto deny;
2099+
}
2100+
2101+
tc_state_fill_from_iphdr_v4(ctx);
2102+
2103+
if (!frags4_handle(ctx)) {
2104+
deny_reason(ctx, CALI_REASON_FRAG_WAIT);
2105+
goto deny;
2106+
}
2107+
/* force it through stack to trigger any further necessary fragmentation */
2108+
ctx->state->flags |= CALI_ST_SKIP_REDIR_ONCE;
2109+
2110+
return pre_policy_processing(ctx);
2111+
2112+
finalize:
2113+
return forward_or_drop(ctx);
2114+
2115+
deny:
2116+
ctx->fwd.res = TC_ACT_SHOT;
2117+
goto finalize;
2118+
}
2119+
#endif /* !IPVER6 */

felix/bpf/hook/load.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,19 @@ func (at AttachType) hasHostConflictProg() bool {
8989
return at.Hook == Egress
9090
}
9191

92+
func (at AttachType) hasIPDefrag() bool {
93+
if at.Family != 4 {
94+
return false
95+
}
96+
97+
switch at.Type {
98+
case tcdefs.EpTypeLO, tcdefs.EpTypeNAT:
99+
return false
100+
}
101+
102+
return at.Hook == Ingress
103+
}
104+
92105
type DefPolicy int
93106

94107
const (

felix/bpf/hook/map.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const (
4040
SubProgTCHostCtConflict
4141
SubProgIcmpInnerNat
4242
SubProgNewFlow
43+
SubProgIPFrag
4344
SubProgTCMainDebug
4445

4546
SubProgXDPMain = SubProgTCMain
@@ -57,6 +58,7 @@ var tcSubProgNames = []string{
5758
"calico_tc_host_ct_conflict",
5859
"calico_tc_skb_icmp_inner_nat",
5960
"calico_tc_skb_new_flow_entrypoint",
61+
"calico_tc_skb_ipv4_frag",
6062
}
6163

6264
var xdpSubProgNames = []string{
@@ -206,6 +208,10 @@ func (pm *ProgramsMap) newLayout(at AttachType, obj *libbpf.Obj) (Layout, error)
206208
continue
207209
}
208210

211+
if SubProg(idx) == SubProgIPFrag && !at.hasIPDefrag() {
212+
continue
213+
}
214+
209215
err := obj.UpdateJumpMap(mapName, subprog, pm.nextIdx)
210216
if err != nil {
211217
return nil, fmt.Errorf("error updating programs map with %s/%s at %d: %w",

felix/bpf/tc/defs/defs.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const (
5555
ProgIndexHostCtConflict
5656
ProgIndexIcmpInnerNat
5757
ProgIndexNewFlow
58+
ProgIndexIPFrag
5859
ProgIndexMainDebug
5960
ProgIndexPolicyDebug
6061
ProgIndexAllowedDebug
@@ -63,6 +64,7 @@ const (
6364
ProgIndexHostCtConflictDebug
6465
ProgIndexIcmpInnerNatDebug
6566
ProgIndexNewFlowDebug
67+
ProgIndexIPFragDebug
6668
ProgIndexEndDebug
6769
ProgIndexEnd
6870

@@ -86,6 +88,7 @@ var ProgramNames = []string{
8688
"calico_tc_host_ct_conflict",
8789
"calico_tc_skb_icmp_inner_nat",
8890
"calico_tc_skb_new_flow_entrypoint",
91+
"calico_tc_skb_ipv4_frag",
8992
/* ipv4 - debug */
9093
"calico_tc_main",
9194
"calico_tc_norm_pol_tail",
@@ -95,6 +98,7 @@ var ProgramNames = []string{
9598
"calico_tc_host_ct_conflict",
9699
"calico_tc_skb_icmp_inner_nat",
97100
"calico_tc_skb_new_flow_entrypoint",
101+
"calico_tc_skb_ipv4_frag",
98102
/* ipv6 */
99103
"calico_tc_main",
100104
"calico_tc_norm_pol_tail",
@@ -104,6 +108,7 @@ var ProgramNames = []string{
104108
"calico_tc_host_ct_conflict",
105109
"calico_tc_skb_icmp_inner_nat",
106110
"calico_tc_skb_new_flow_entrypoint",
111+
"",
107112
/* ipv6 - debug */
108113
"calico_tc_main",
109114
"calico_tc_norm_pol_tail",
@@ -113,6 +118,7 @@ var ProgramNames = []string{
113118
"calico_tc_host_ct_conflict",
114119
"calico_tc_skb_icmp_inner_nat",
115120
"calico_tc_skb_new_flow_entrypoint",
121+
"",
116122
}
117123

118124
type ToOrFromEp string

felix/bpf/ut/bpf_prog_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ var tcJumpMapIndexes = map[string][]int{
212212
tcdefs.ProgIndexHostCtConflict,
213213
tcdefs.ProgIndexIcmpInnerNat,
214214
tcdefs.ProgIndexNewFlow,
215+
tcdefs.ProgIndexIPFrag,
215216
},
216217
"IPv4 debug": []int{
217218
tcdefs.ProgIndexMainDebug,
@@ -222,6 +223,7 @@ var tcJumpMapIndexes = map[string][]int{
222223
tcdefs.ProgIndexHostCtConflictDebug,
223224
tcdefs.ProgIndexIcmpInnerNatDebug,
224225
tcdefs.ProgIndexNewFlowDebug,
226+
tcdefs.ProgIndexIPFragDebug,
225227
},
226228
"IPv6": []int{
227229
tcdefs.ProgIndexMain,

0 commit comments

Comments
 (0)