今天分析OVS_ACTION_ATTR_RECIRC action的处理函数execute_recirc。
1、execute_recirc函数
static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
struct sw_flow_key *key,
const struct nlattr *a, int rem)
{
struct deferred_action *da;
if (!is_flow_key_valid(key)) { //如果key为valid,需要重新生成key
int err;
err = ovs_flow_key_update(skb, key); //重新生成key
if (err)
return err;
}
BUG_ON(!is_flow_key_valid(key));
if (!nla_is_last(a, rem)) { //如果action不是最后一个,则需要克隆skb
/* Recirc action is the not the last action
* of the action list, need to clone the skb.
*/
skb = skb_clone(skb, GFP_ATOMIC);
/* Skip the recirc action when out of memory, but
* continue on with the rest of the action list.
*/
if (!skb)
return 0;
}
da = add_deferred_actions(skb, key, NULL); //添加deferred action
if (da) {
da->pkt_key.recirc_id = nla_get_u32(a);
} else {
kfree_skb(skb);