openvswitch源码分析“Flow actions may not be safe on all matching packets.”

120阅读 0评论2021-07-23 hiyachen
分类:云计算

openvswitch2.13.0
openvswitch/datapath/datapath.c文件(L967行)中:
    /* Validate actions. */
    error = ovs_nla_copy_actions(net, a[OVS_FLOW_ATTR_ACTIONS],
                     &new_flow->key, &acts, log);
    if (error) {
        OVS_NLERR(log, "Flow actions may not be safe on all matching packets.");
        goto err_kfree_flow;
    }

在openvswitch/datapath/flow_netlink.c文件(L3247)中有ovs_nla_copy_actions函数的实现:
/* 'key' must be the masked key. */
int ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
             const struct sw_flow_key *key,
             struct sw_flow_actions **sfa, bool log)
{
    int err;
    u32 mpls_label_count = 0;

    *sfa = nla_alloc_flow_actions(min(nla_len(attr), MAX_ACTIONS_BUFSIZE));
    if (IS_ERR(*sfa))
        return PTR_ERR(*sfa);

    if (eth_p_mpls(key->eth.type))
        mpls_label_count = hweight_long(key->mpls.num_labels_mask);

    (*sfa)->orig_len = nla_len(attr);
    err = __ovs_nla_copy_actions(net, attr, key, sfa, key->eth.type,
                     key->eth.vlan.tci, mpls_label_count, log);
    if (err)
        ovs_nla_free_flow_actions(*sfa);

    return err;
}

在openvswitch/datapath/linux/compat/include/linux/openvswitch.h文件(L993)中有action的定义:
enum ovs_action_attr {
    OVS_ACTION_ATTR_UNSPEC,
    OVS_ACTION_ATTR_OUTPUT,          /* u32 port number. */
    OVS_ACTION_ATTR_USERSPACE,    /* Nested OVS_USERSPACE_ATTR_*. */
    OVS_ACTION_ATTR_SET,          /* One nested OVS_KEY_ATTR_*. */
    OVS_ACTION_ATTR_PUSH_VLAN,    /* struct ovs_action_push_vlan. */
    OVS_ACTION_ATTR_POP_VLAN,     /* No argument. */
    OVS_ACTION_ATTR_SAMPLE,       /* Nested OVS_SAMPLE_ATTR_*. */
    OVS_ACTION_ATTR_RECIRC,       /* u32 recirc_id. */
    OVS_ACTION_ATTR_HASH,          /* struct ovs_action_hash. */
    OVS_ACTION_ATTR_PUSH_MPLS,    /* struct ovs_action_push_mpls. */
    OVS_ACTION_ATTR_POP_MPLS,     /* __be16 ethertype. */
    OVS_ACTION_ATTR_SET_MASKED,   /* One nested OVS_KEY_ATTR_* including
                       * data immediately followed by a mask.
                       * The data must be zero for the unmasked
                       * bits. */
    OVS_ACTION_ATTR_CT,           /* Nested OVS_CT_ATTR_* . */
    OVS_ACTION_ATTR_TRUNC,        /* u32 struct ovs_action_trunc. */
    OVS_ACTION_ATTR_PUSH_ETH,     /* struct ovs_action_push_eth. */
    OVS_ACTION_ATTR_POP_ETH,      /* No argument. */
    OVS_ACTION_ATTR_CT_CLEAR,     /* No argument. */
    OVS_ACTION_ATTR_PUSH_NSH,     /* Nested OVS_NSH_KEY_ATTR_*. */
    OVS_ACTION_ATTR_POP_NSH,      /* No argument. */
    OVS_ACTION_ATTR_METER,        /* u32 meter number. */
    OVS_ACTION_ATTR_CLONE,        /* Nested OVS_CLONE_ATTR_*.  */
    OVS_ACTION_ATTR_CHECK_PKT_LEN, /* Nested OVS_CHECK_PKT_LEN_ATTR_*. */

#ifndef __KERNEL__
    OVS_ACTION_ATTR_TUNNEL_PUSH,   /* struct ovs_action_push_tnl*/
    OVS_ACTION_ATTR_TUNNEL_POP,    /* u32 port number. */
    OVS_ACTION_ATTR_DROP,          /* u32 xlate_error. */
#endif
    __OVS_ACTION_ATTR_MAX,          /* Nothing past this will be accepted
                       * from userspace. */

#ifdef __KERNEL__
    OVS_ACTION_ATTR_SET_TO_MASKED, /* Kernel module internal masked
                    * set action converted from
                    * OVS_ACTION_ATTR_SET. */
#endif
};


上一篇:Libvirt API及调用
下一篇:openvswitch源码分析网络包流向