diff --git a/common/llb_dp_mdi.h b/common/llb_dp_mdi.h index d02dfd6..43b21f2 100644 --- a/common/llb_dp_mdi.h +++ b/common/llb_dp_mdi.h @@ -42,10 +42,9 @@ do { \ #define LLBS_PPLN_TRAPC(F,C) \ do { \ F->pm.pipe_act |= LLB_PIPE_TRAP; \ - F->pm.rcode = C; \ + F->pm.rcode |= C; \ } while (0) - #define LLB_DP_FC_HCAP_FLAGS (LLB_DP_CTM_HIT|LLB_DP_NAT_HIT) #define LL_PIPE_FC_CAP(x) \ @@ -87,7 +86,7 @@ struct dp_pi_mdi { #define LLB_PIPE_PASS 0x8 #define LLB_PIPE_REWIRE 0x10 #define LLB_PIPE_RDR_PRIO 0x20 -#define LLB_PIPE_SET_CT 0x40 +#define LLB_PIPE_SET_CT 0x40 __u8 pipe_act; __u8 l3_off; #define LLB_DP_TMAC_HIT 0x1 diff --git a/kernel/llb_kern_devif.c b/kernel/llb_kern_devif.c index df56f77..be2b453 100644 --- a/kernel/llb_kern_devif.c +++ b/kernel/llb_kern_devif.c @@ -518,7 +518,7 @@ dp_ing_ct_main(void *ctx, struct xfi *xf) * and start over. But simplicity wins against * complexity for now */ - dp_l3_fwd(ctx, xf, fa); + dp_l3_fwd(ctx, xf, fa, 0); /* Perform masquerading if necessary */ if ((xf->pm.phit & LLB_DP_CTM_HIT) == 0) { @@ -537,7 +537,7 @@ dp_ing_ct_main(void *ctx, struct xfi *xf) } xf->nm.ct_sts = LLB_PIPE_CT_INP; - dp_l3tun_fwd(ctx, xf, fa); + dp_l3_fwd(ctx, xf, fa, 1); dp_eg_l2(ctx, xf, fa); res_end: diff --git a/kernel/llb_kern_l3fwd.c b/kernel/llb_kern_l3fwd.c index 15ee4d0..ecb4719 100644 --- a/kernel/llb_kern_l3fwd.c +++ b/kernel/llb_kern_l3fwd.c @@ -195,6 +195,7 @@ dp_do_rtv6(void *ctx, struct xfi *xf, void *fa_) act = bpf_map_lookup_elem(&rt_v6_map, key); if (!act) { + // Dont masquerade before doing PASS xf->pm.nf &= ~LLB_NAT_SRC; if (!DP_LLB_IS_EGR(ctx)) { LLBS_PPLN_TRAPC(xf, LLB_PIPE_RC_RT_TRAP); @@ -400,8 +401,26 @@ dp_do_ing_ct(void *ctx, struct xfi *xf, void *fa_) } static void __always_inline -dp_do_ipv4_fwd(void *ctx, struct xfi *xf, void *fa_) +dp_do_ipv4_fwd(void *ctx, struct xfi *xf, void *fa_, int dir) { + if (dir == 1) { + if (xf->l2m.dl_type == bpf_htons(ETH_P_IP)) { + /* Check tunnel initiation */ + if (xf->tm.tunnel_id == 0 || xf->tm.tun_type != LLB_TUN_GTP) { + dp_do_sess4_lkup(ctx, xf); + if (xf->tm.new_tunnel_id == 0 && !(xf->pm.nf & (LLB_NAT_DST|LLB_NAT_SRC))) { + return; + } + } + } + + if (xf->pm.pipe_act & LLB_PIPE_TRAP && + xf->pm.rcode & LLB_PIPE_RC_RT_TRAP) { + xf->pm.pipe_act &= ~LLB_PIPE_TRAP; + xf->pm.rcode &= ~LLB_PIPE_RC_RT_TRAP; + } + } + #ifndef HAVE_DP_LBMODE_ONLY if (xf->pm.phit & LLB_DP_TMAC_HIT) { #else @@ -418,7 +437,7 @@ dp_do_ipv4_fwd(void *ctx, struct xfi *xf, void *fa_) } static void __always_inline -dp_do_ipv6_fwd(void *ctx, struct xfi *xf, void *fa_) +dp_do_ipv6_fwd(void *ctx, struct xfi *xf, void *fa_, int dir) { #ifndef HAVE_DP_LBMODE_ONLY @@ -437,49 +456,21 @@ dp_do_ipv6_fwd(void *ctx, struct xfi *xf, void *fa_) } static int __always_inline -dp_l3tun_fwd(void *ctx, struct xfi *xf, void *fa) -{ - if (xf->l2m.dl_type == bpf_htons(ETH_P_IP)) { - /* Check tunnel initiation */ - if (xf->tm.tunnel_id == 0 || xf->tm.tun_type != LLB_TUN_GTP) { - dp_do_sess4_lkup(ctx, xf); - if (xf->tm.new_tunnel_id == 0) { - return 0; - } - } -#ifndef HAVE_DP_LBMODE_ONLY - if (xf->pm.phit & LLB_DP_TMAC_HIT) { -#else - if (1) { -#endif - - /* If some pipeline block already set a redirect before this, - * we honor this and dont do further l3 processing - */ - if ((xf->pm.pipe_act & LLB_PIPE_RDR_MASK) == 0) { - dp_do_rtv4(ctx, xf, fa); - } - } - } - return 0; -} - -static int __always_inline -dp_l3_fwd(void *ctx, struct xfi *xf, void *fa) +dp_l3_fwd(void *ctx, struct xfi *xf, void *fa, int dir) { if (xf->l2m.dl_type == bpf_htons(ETH_P_IP)) { if (xf->pm.nf && xf->nm.nv6 != 0) { xf->nm.xlate_proto = 1; - dp_do_ipv6_fwd(ctx, xf, fa); + dp_do_ipv6_fwd(ctx, xf, fa, dir); } else { - dp_do_ipv4_fwd(ctx, xf, fa); + dp_do_ipv4_fwd(ctx, xf, fa, dir); } } else if (xf->l2m.dl_type == bpf_htons(ETH_P_IPV6)) { if (xf->pm.nf && xf->nm.nv6 == 0) { xf->nm.xlate_proto = 1; - dp_do_ipv4_fwd(ctx, xf, fa); + dp_do_ipv4_fwd(ctx, xf, fa, dir); } else { - dp_do_ipv6_fwd(ctx, xf, fa); + dp_do_ipv6_fwd(ctx, xf, fa, dir); } } return 0; @@ -496,9 +487,8 @@ dp_ing_l3(void *ctx, struct xfi *xf, void *fa) } } - dp_l3_fwd(ctx, xf, fa); dp_do_ing_ct(ctx, xf, fa); - dp_l3tun_fwd(ctx, xf, fa); + dp_l3_fwd(ctx, xf, fa, 1); return 0; }