@@ -1689,6 +1689,12 @@ static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev,
16891689static  int  __bpf_redirect_common (struct  sk_buff  * skb , struct  net_device  * dev ,
16901690				 u32  flags )
16911691{
1692+ 	/* Verify that a link layer header is carried */ 
1693+ 	if  (unlikely (skb -> mac_header  >= skb -> network_header )) {
1694+ 		kfree_skb (skb );
1695+ 		return  - ERANGE ;
1696+ 	}
1697+ 
16921698	bpf_push_mac_rcsum (skb );
16931699	return  flags  &  BPF_F_INGRESS  ?
16941700	       __bpf_rx_skb (dev , skb ) : __bpf_tx_skb (dev , skb );
@@ -2188,12 +2194,53 @@ static const struct bpf_func_proto bpf_skb_change_tail_proto = {
21882194	.arg3_type 	=  ARG_ANYTHING ,
21892195};
21902196
2197+ BPF_CALL_3 (bpf_skb_change_head , struct  sk_buff  * , skb , u32 , head_room ,
2198+ 	   u64 , flags )
2199+ {
2200+ 	u32  max_len  =  __bpf_skb_max_len (skb );
2201+ 	u32  new_len  =  skb -> len  +  head_room ;
2202+ 	int  ret ;
2203+ 
2204+ 	if  (unlikely (flags  ||  (!skb_is_gso (skb ) &&  new_len  >  max_len ) || 
2205+ 		     new_len  <  skb -> len ))
2206+ 		return  - EINVAL ;
2207+ 
2208+ 	ret  =  skb_cow (skb , head_room );
2209+ 	if  (likely (!ret )) {
2210+ 		/* Idea for this helper is that we currently only 
2211+ 		 * allow to expand on mac header. This means that 
2212+ 		 * skb->protocol network header, etc, stay as is. 
2213+ 		 * Compared to bpf_skb_change_tail(), we're more 
2214+ 		 * flexible due to not needing to linearize or 
2215+ 		 * reset GSO. Intention for this helper is to be 
2216+ 		 * used by an L3 skb that needs to push mac header 
2217+ 		 * for redirection into L2 device. 
2218+ 		 */ 
2219+ 		__skb_push (skb , head_room );
2220+ 		memset (skb -> data , 0 , head_room );
2221+ 		skb_reset_mac_header (skb );
2222+ 	}
2223+ 
2224+ 	bpf_compute_data_end (skb );
2225+ 	return  0 ;
2226+ }
2227+ 
2228+ static  const  struct  bpf_func_proto  bpf_skb_change_head_proto  =  {
2229+ 	.func 		=  bpf_skb_change_head ,
2230+ 	.gpl_only 	=  false,
2231+ 	.ret_type 	=  RET_INTEGER ,
2232+ 	.arg1_type 	=  ARG_PTR_TO_CTX ,
2233+ 	.arg2_type 	=  ARG_ANYTHING ,
2234+ 	.arg3_type 	=  ARG_ANYTHING ,
2235+ };
2236+ 
21912237bool  bpf_helper_changes_skb_data (void  * func )
21922238{
21932239	if  (func  ==  bpf_skb_vlan_push  || 
21942240	    func  ==  bpf_skb_vlan_pop  || 
21952241	    func  ==  bpf_skb_store_bytes  || 
21962242	    func  ==  bpf_skb_change_proto  || 
2243+ 	    func  ==  bpf_skb_change_head  || 
21972244	    func  ==  bpf_skb_change_tail  || 
21982245	    func  ==  bpf_skb_pull_data  || 
21992246	    func  ==  bpf_l3_csum_replace  || 
@@ -2639,6 +2686,68 @@ cg_skb_func_proto(enum bpf_func_id func_id)
26392686	}
26402687}
26412688
2689+ static  const  struct  bpf_func_proto  * 
2690+ lwt_inout_func_proto (enum  bpf_func_id  func_id )
2691+ {
2692+ 	switch  (func_id ) {
2693+ 	case  BPF_FUNC_skb_load_bytes :
2694+ 		return  & bpf_skb_load_bytes_proto ;
2695+ 	case  BPF_FUNC_skb_pull_data :
2696+ 		return  & bpf_skb_pull_data_proto ;
2697+ 	case  BPF_FUNC_csum_diff :
2698+ 		return  & bpf_csum_diff_proto ;
2699+ 	case  BPF_FUNC_get_cgroup_classid :
2700+ 		return  & bpf_get_cgroup_classid_proto ;
2701+ 	case  BPF_FUNC_get_route_realm :
2702+ 		return  & bpf_get_route_realm_proto ;
2703+ 	case  BPF_FUNC_get_hash_recalc :
2704+ 		return  & bpf_get_hash_recalc_proto ;
2705+ 	case  BPF_FUNC_perf_event_output :
2706+ 		return  & bpf_skb_event_output_proto ;
2707+ 	case  BPF_FUNC_get_smp_processor_id :
2708+ 		return  & bpf_get_smp_processor_id_proto ;
2709+ 	case  BPF_FUNC_skb_under_cgroup :
2710+ 		return  & bpf_skb_under_cgroup_proto ;
2711+ 	default :
2712+ 		return  sk_filter_func_proto (func_id );
2713+ 	}
2714+ }
2715+ 
2716+ static  const  struct  bpf_func_proto  * 
2717+ lwt_xmit_func_proto (enum  bpf_func_id  func_id )
2718+ {
2719+ 	switch  (func_id ) {
2720+ 	case  BPF_FUNC_skb_get_tunnel_key :
2721+ 		return  & bpf_skb_get_tunnel_key_proto ;
2722+ 	case  BPF_FUNC_skb_set_tunnel_key :
2723+ 		return  bpf_get_skb_set_tunnel_proto (func_id );
2724+ 	case  BPF_FUNC_skb_get_tunnel_opt :
2725+ 		return  & bpf_skb_get_tunnel_opt_proto ;
2726+ 	case  BPF_FUNC_skb_set_tunnel_opt :
2727+ 		return  bpf_get_skb_set_tunnel_proto (func_id );
2728+ 	case  BPF_FUNC_redirect :
2729+ 		return  & bpf_redirect_proto ;
2730+ 	case  BPF_FUNC_clone_redirect :
2731+ 		return  & bpf_clone_redirect_proto ;
2732+ 	case  BPF_FUNC_skb_change_tail :
2733+ 		return  & bpf_skb_change_tail_proto ;
2734+ 	case  BPF_FUNC_skb_change_head :
2735+ 		return  & bpf_skb_change_head_proto ;
2736+ 	case  BPF_FUNC_skb_store_bytes :
2737+ 		return  & bpf_skb_store_bytes_proto ;
2738+ 	case  BPF_FUNC_csum_update :
2739+ 		return  & bpf_csum_update_proto ;
2740+ 	case  BPF_FUNC_l3_csum_replace :
2741+ 		return  & bpf_l3_csum_replace_proto ;
2742+ 	case  BPF_FUNC_l4_csum_replace :
2743+ 		return  & bpf_l4_csum_replace_proto ;
2744+ 	case  BPF_FUNC_set_hash_invalid :
2745+ 		return  & bpf_set_hash_invalid_proto ;
2746+ 	default :
2747+ 		return  lwt_inout_func_proto (func_id );
2748+ 	}
2749+ }
2750+ 
26422751static  bool  __is_valid_access (int  off , int  size , enum  bpf_access_type  type )
26432752{
26442753	if  (off  <  0  ||  off  >= sizeof (struct  __sk_buff ))
@@ -2676,6 +2785,39 @@ static bool sk_filter_is_valid_access(int off, int size,
26762785	return  __is_valid_access (off , size , type );
26772786}
26782787
2788+ static  bool  lwt_is_valid_access (int  off , int  size ,
2789+ 				enum  bpf_access_type  type ,
2790+ 				enum  bpf_reg_type  * reg_type )
2791+ {
2792+ 	switch  (off ) {
2793+ 	case  offsetof(struct  __sk_buff , tc_classid ):
2794+ 		return  false;
2795+ 	}
2796+ 
2797+ 	if  (type  ==  BPF_WRITE ) {
2798+ 		switch  (off ) {
2799+ 		case  offsetof(struct  __sk_buff , mark ):
2800+ 		case  offsetof(struct  __sk_buff , priority ):
2801+ 		case  offsetof(struct  __sk_buff , cb [0 ]) ...
2802+ 		     offsetof(struct  __sk_buff , cb [4 ]):
2803+ 			break ;
2804+ 		default :
2805+ 			return  false;
2806+ 		}
2807+ 	}
2808+ 
2809+ 	switch  (off ) {
2810+ 	case  offsetof(struct  __sk_buff , data ):
2811+ 		* reg_type  =  PTR_TO_PACKET ;
2812+ 		break ;
2813+ 	case  offsetof(struct  __sk_buff , data_end ):
2814+ 		* reg_type  =  PTR_TO_PACKET_END ;
2815+ 		break ;
2816+ 	}
2817+ 
2818+ 	return  __is_valid_access (off , size , type );
2819+ }
2820+ 
26792821static  int  tc_cls_act_prologue (struct  bpf_insn  * insn_buf , bool  direct_write ,
26802822			       const  struct  bpf_prog  * prog )
26812823{
@@ -3007,6 +3149,19 @@ static const struct bpf_verifier_ops cg_skb_ops = {
30073149	.convert_ctx_access 	=  sk_filter_convert_ctx_access ,
30083150};
30093151
3152+ static  const  struct  bpf_verifier_ops  lwt_inout_ops  =  {
3153+ 	.get_func_proto 		=  lwt_inout_func_proto ,
3154+ 	.is_valid_access 	=  lwt_is_valid_access ,
3155+ 	.convert_ctx_access 	=  sk_filter_convert_ctx_access ,
3156+ };
3157+ 
3158+ static  const  struct  bpf_verifier_ops  lwt_xmit_ops  =  {
3159+ 	.get_func_proto 		=  lwt_xmit_func_proto ,
3160+ 	.is_valid_access 	=  lwt_is_valid_access ,
3161+ 	.convert_ctx_access 	=  sk_filter_convert_ctx_access ,
3162+ 	.gen_prologue 		=  tc_cls_act_prologue ,
3163+ };
3164+ 
30103165static  struct  bpf_prog_type_list  sk_filter_type  __read_mostly  =  {
30113166	.ops 	=  & sk_filter_ops ,
30123167	.type 	=  BPF_PROG_TYPE_SOCKET_FILTER ,
@@ -3032,13 +3187,31 @@ static struct bpf_prog_type_list cg_skb_type __read_mostly = {
30323187	.type 	=  BPF_PROG_TYPE_CGROUP_SKB ,
30333188};
30343189
3190+ static  struct  bpf_prog_type_list  lwt_in_type  __read_mostly  =  {
3191+ 	.ops 	=  & lwt_inout_ops ,
3192+ 	.type 	=  BPF_PROG_TYPE_LWT_IN ,
3193+ };
3194+ 
3195+ static  struct  bpf_prog_type_list  lwt_out_type  __read_mostly  =  {
3196+ 	.ops 	=  & lwt_inout_ops ,
3197+ 	.type 	=  BPF_PROG_TYPE_LWT_OUT ,
3198+ };
3199+ 
3200+ static  struct  bpf_prog_type_list  lwt_xmit_type  __read_mostly  =  {
3201+ 	.ops 	=  & lwt_xmit_ops ,
3202+ 	.type 	=  BPF_PROG_TYPE_LWT_XMIT ,
3203+ };
3204+ 
30353205static  int  __init  register_sk_filter_ops (void )
30363206{
30373207	bpf_register_prog_type (& sk_filter_type );
30383208	bpf_register_prog_type (& sched_cls_type );
30393209	bpf_register_prog_type (& sched_act_type );
30403210	bpf_register_prog_type (& xdp_type );
30413211	bpf_register_prog_type (& cg_skb_type );
3212+ 	bpf_register_prog_type (& lwt_in_type );
3213+ 	bpf_register_prog_type (& lwt_out_type );
3214+ 	bpf_register_prog_type (& lwt_xmit_type );
30423215
30433216	return  0 ;
30443217}
0 commit comments