datapath/actions.c
/* Execute the actions on the clone of the packet. The effect of the
 * execution does not affect the original 'skb' nor the original 'key'.
 *
 * The execution may be deferred in case the actions can not be executed
 * immediately.
 */
Execute the actions on the clone of the packet. The effect of the
execution does not affect the original 'skb' nor the original 'key'.

The execution may be deferred in case the actions can not be executed
immediately.
Execute the actions on the clone of the packet . The effect of the execution does not affect the original ' skb ' nor the original ' key ' . The execution may be deferred in case the actions can not be executed immediately .
static int clone_execute(struct datapath *dp, struct sk_buff *skb,
			 struct sw_flow_key *key, u32 recirc_id,
			 const struct nlattr *actions, int len,
			 bool last, bool clone_flow_key)
{
	struct deferred_action *da;
	struct sw_flow_key *clone;
	skb = last ? skb : skb_clone(skb, GFP_ATOMIC);
	if (!skb) {
		return 0;
	}
	clone = clone_flow_key ? clone_key(key) : key;
	if (clone) {
		int err = 0;
		if (actions) { 
			if (clone_flow_key)
				__this_cpu_inc(exec_actions_level);
			err = do_execute_actions(dp, skb, clone,
						 actions, len);
			if (clone_flow_key)
				__this_cpu_dec(exec_actions_level);
		} else { 
			clone->recirc_id = recirc_id;
			ovs_dp_process_packet(skb, clone);
		}
		return err;
	}
	da = add_deferred_actions(skb, key, actions, len);
	if (da) {
		if (!actions) { 
			key = &da->pkt_key;
			key->recirc_id = recirc_id;
		}
	} else {
		kfree_skb(skb);
		if (net_ratelimit()) {
			if (actions) { 
				pr_warn("%s: deferred action limit reached, drop sample action\n",
					ovs_dp_name(dp));
			} else {  
				pr_warn("%s: deferred action limit reached, drop recirc action\n",
					ovs_dp_name(dp));
			}
		}
	}
	return 0;
}
static int clone_execute ( struct datapath * dp , struct sk_buff * skb , struct sw_flow_key * key , u32 recirc_id , const struct nlattr * actions , int len , bool last , bool clone_flow_key ) { struct deferred_action * da ; struct sw_flow_key * clone ; skb = last ? skb : skb_clone ( skb , GFP_ATOMIC ) ; if ( ! skb ) { return 0 ; } clone = clone_flow_key ? clone_key ( key ) : key ; if ( clone ) { int err = 0 ; if ( actions ) { if ( clone_flow_key ) __this_cpu_inc ( exec_actions_level ) ; err = do_execute_actions ( dp , skb , clone , actions , len ) ; if ( clone_flow_key ) __this_cpu_dec ( exec_actions_level ) ; } else { clone -> recirc_id = recirc_id ; ovs_dp_process_packet ( skb , clone ) ; } return err ; } da = add_deferred_actions ( skb , key , actions , len ) ; if ( da ) { if ( ! actions ) { key = & da -> pkt_key ; key -> recirc_id = recirc_id ; } } else { kfree_skb ( skb ) ; if ( net_ratelimit ( ) ) { if ( actions ) { pr_warn ( " \n " , ovs_dp_name ( dp ) ) ; } else { pr_warn ( " \n " , ovs_dp_name ( dp ) ) ; } } } return 0 ; }
Execute the actions on the clone of the packet.
Execute the actions on the clone of the packet .
/* Out of memory, skip this action.
		 */ /* When clone_flow_key is false, the 'key' will not be change
	 * by the actions, then the 'key' can be used directly.
	 * Otherwise, try to clone key from the next recursion level of
	 * 'flow_keys'. If clone is successful, execute the actions
	 * without deferring.
	 */ /* Sample action */ /* Recirc action */ /* Out of 'flow_keys' space. Defer actions */ /* Recirc action */ /* Out of per CPU action FIFO space. Drop the 'skb' and
		 * log an error.
		 */ /* Sample action */ /* Recirc action */