ovs learn action

本文主要记录下 learn action的操作,learn action用来动态添加openflow流表,包括匹配域,action和其他属性。

主要还是参考源码和ovs-action,也可参考官网的例子

learn action
  Thelearnaction
       Syntax:
              learn(argument...)

       The learn action adds or modifies a flow in an OpenFlow table,
       similar to ovs-ofctl --strict mod-flows. The arguments specify
       the match fields, actions, and other properties of the flow to be
       added or modified.
       learn的参数指定了匹配域,动作和其他流的属性。

       Match fields for the new flow are specified as follows. At least
       one match field should ordinarily be specified:
       对于新添加的流表,匹配域按如下格式指定,field 是标准的字段,
       可参考 https://man7.org/linux/man-pages/man7/ovs-fields.7.html
       
                field = value, value为任意值
              field=value
                     Specifies that field, in the new flow, must match
                     the literal value, e.g. dl_type=0x800. Shorthand
                     match syntax, such as ip in place of dl_type=0x800,
                     is not supported.

                field=src,src为正常处理的报文中的字段
              field=src
                     Specifies that field in the new flow must match src
                     taken from the packet currently being processed.
                     For example, udp_dst=udp_src, applied to a UDP
                     packet with source port 53, creates a flow which
                     matches udp_dst=53. field and src must have the
                     same width.

                field 上面的格式,如果field和src相等,则可简写为field
              field  Shorthand for the previous form when field and src
                     are the same. For example, udp_dst, applied to a
                     UDP packet with destination port 53, creates a flow
                     which matches udp_dst=53.

       The field and src arguments above should be fields or subfields
       in the syntax described under ``Field Specifications’’ above.

       Match field specifications must honor prerequisites for both the
       flow with the learn and the new flow that it creates. Consider
       the following complete flow, in the syntax accepted by ovs-ofctl.
       If the flow’s match on udp were omitted, then the flow would not
       satisfy the prerequisites for the learn action’s use of udp_src.
       If dl_type=0x800 or nw_proto were omitted from learn, then the
       new flow would not satisfy the prerequisite for its match on
       udp_dst. For more information on prerequisites, please refer to
       ovs-fields(7):

               udp, actions=learn(dl_type=0x800, nw_proto=17, udp_dst=udp_src)

        新流表的action按如下格式添加,至少指定一个action。
        learn只支持给新流表添加两种action: load 和 output
       Actions for the new flow are specified as follows. At least one
       action should ordinarily be specified:

                将任意值value加载进dst
              load:value->dst
                     Adds a load action to the new flow that loads the
                     literal value into dst. The syntax is the same as
                     the load action explained in the ``Header
                     Modification’’ section.

                将正在处理的报文的field或者子field,加载进dst
              load:src->dst
                     Adds a load action to the new flow that loads src,
                     a field or subfield from the packet being
                     processed, into dst.
                     
                load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15])
                
              output:field
                     Adds an output action to the new flow’s actions
                     that outputs to the OpenFlow port taken from field,
                     which must be a field as described above.

              fin_idle_timeout=seconds
              fin_hard_timeout=seconds
                   Adds a fin_timeout action with the specified
                   arguments to the new flow. This feature was added in
                   Open vSwitch 1.5.90.

        还有下面额外的参数需要添加到flow
       The following additional arguments are optional:

              idle_timeout=seconds
              hard_timeout=seconds
              priority=value
              cookie=value
              send_flow_rem
                   These arguments have the same meaning as in the usual
                   flow syntax documented in ovs-ofctl(8).

              table=table
                   The table in which the new flow should be inserted.
                   Specify a decimal number between 0 and 254 inclusive
                   or the name of a table. The default, if table is
                   unspecified, is table 1 (not 0).

              delete_learned
                   When this flag is specified, deleting the flow that
                   contains the learn action will also delete the flows
                   created by learn. Specifically, when the last learn
                   action with this flag and particular table and cookie
                   values is removed, the switch deletes all of the
                   flows in the specified table with the specified
                   cookie.

                   This flag was added in Open vSwitch 2.4.

              limit=number
                   If the number of flows in the new flow’s table with
                   the same cookie exceeds number, the action will not
                   add a new flow. By default, or with limit=0, there is
                   no limit.

                   This flag was added in Open vSwitch 2.8.

              result_dst=field[bit]
                   If learn fails (because the number of flows exceeds
                   limit), the action sets field[bit] to 0, otherwise it
                   will be set to 1. field[bit] must be a single bit.

                   This flag was added in Open vSwitch 2.8.

        learn只支持给新流表添加两种action: load 和 output
       By itself, the learn action can only put two kinds of actions
       into the flows that it creates: load and output actions. If learn
       is used in isolation, these are severe limits.

       However, learn is not meant to be used in isolation. It is a
       primitive meant to be used together with other Open vSwitch
       features to accomplish a task. Its existing features are enough
       to accomplish most tasks.

       Here is an outline of a typical pipeline structure that allows
       for versatile behavior using learn:

              •      Flows in table A contain a learn action, that
                     populates flows in table L, that use a load action
                     to populate register R with information about what
                     was learned.

              •      Flows in table B contain two sequential resubmit
                     actions: one to table L and another one to table
                     B+1.

              •      Flows in table B+1 match on register R and act
                     differently depending on what the flows in table L
                     loaded into it.

       This approach can be used to implement many learn-based features.
       For example:

              •      Resubmit to a table selected based on learned
                     information, e.g. see ⟨https://
                     mail.openvswitch.org/pipermail/ovs-discuss/
                     2016-June/021694.html⟩ .

              •      MAC learning in the middle of a pipeline, as
                     described in the ``Open vSwitch Advanced Features
                     Tutorial’’ in the OVS documentation.

              •      TCP state based firewalling, by learning outgoing
                     connections based on SYN packets and matching them
                     up with incoming packets. (This is usually better
                     implemented using the ct action.)

              •      At least some of the features described in T. A.
                     Hoff, ``Extending Open vSwitch to Facilitate
                     Creation of Stateful SDN Applications’’.

       Conformance:

       The learn action is an Open vSwitch extension to OpenFlow added
       in Open vSwitch 1.3. Some features of learn were added in later
       versions, as noted individually above.

命令行解析

#define NX_LEARN_SRC_FIELD     (0 << 13) /* Copy from field. */           表示源值为 field
#define NX_LEARN_SRC_IMMEDIATE (1 << 13) /* Copy from immediate value. */ 表示源值为立即数

#define NX_LEARN_DST_MATCH     (0 << 11) /* Add match criterion. */       表示添加匹配域
#define NX_LEARN_DST_LOAD      (1 << 11) /* Add NXAST_REG_LOAD action. */ 表示添加load action
#define NX_LEARN_DST_OUTPUT    (2 << 11) /* Add OFPAT_OUTPUT action. */   表示添加 output action

/* Part of struct ofpact_learn, below. */
struct ofpact_learn_spec {
    OFPACT_PADDED_MEMBERS(
        struct mf_subfield src;    /* NX_LEARN_SRC_FIELD only. */
        struct mf_subfield dst;    /* NX_LEARN_DST_MATCH,
                                    * NX_LEARN_DST_LOAD only. */
        uint16_t src_type;         /* One of NX_LEARN_SRC_*. */
        uint16_t dst_type;         /* One of NX_LEARN_DST_*. */
        uint8_t n_bits;            /* Number of bits in source and dest. */
    );
    /* Followed by 'DIV_ROUND_UP(n_bits, 8)' bytes of immediate data for
     * match 'dst_type's NX_LEARN_DST_MATCH and NX_LEARN_DST_LOAD when
     * NX_LEARN_SRC_IMMEDIATE is set in 'src_type', followed by zeroes to align
     * to OFPACT_ALIGNTO. */
};

struct ofpact_learn {
    OFPACT_PADDED_MEMBERS(
        struct ofpact ofpact;

        uint16_t idle_timeout;     /* Idle time before discarding (seconds). */
        uint16_t hard_timeout;     /* Max time before discarding (seconds). */
        uint16_t priority;         /* Priority level of flow entry. */
        uint8_t table_id;          /* Table to insert flow entry. */
        enum nx_learn_flags flags; /* NX_LEARN_F_*. */
        ovs_be64 cookie;           /* Cookie for new flow. */
        uint16_t fin_idle_timeout; /* Idle timeout after FIN, if nonzero. */
        uint16_t fin_hard_timeout; /* Hard timeout after FIN, if nonzero. */
        /* If the number of flows on 'table_id' with 'cookie' exceeds this,
         * the action will not add a new flow. 0 indicates unlimited. */
        uint32_t limit;
        /* Used only if 'flags' has NX_LEARN_F_WRITE_RESULT.  If the execution
         * failed to install a new flow because 'limit' is exceeded,
         * result_dst will be set to 0, otherwise to 1. */
        struct mf_subfield result_dst;
    );

    struct ofpact_learn_spec specs[];
};

###命令行解析
static char * OVS_WARN_UNUSED_RESULT
parse_LEARN(char *arg, const struct ofputil_port_map *port_map,
            struct ofpbuf *ofpacts,
            enum ofputil_protocol *usable_protocols OVS_UNUSED)
{
    return learn_parse(arg, port_map, ofpacts);
}

char * OVS_WARN_UNUSED_RESULT
learn_parse(char *arg, const struct ofputil_port_map *port_map,
            struct ofpbuf *ofpacts)
{
    char *orig = xstrdup(arg);
    char *error = learn_parse__(orig, arg, port_map, ofpacts);
    free(orig);
    return error;
}

static char * OVS_WARN_UNUSED_RESULT
learn_parse__(char *orig, char *arg, const struct ofputil_port_map *port_map,
              struct ofpbuf *ofpacts)
    struct ofpact_learn *learn;
    struct match match;
    char *name, *value;

    learn = ofpact_put_LEARN(ofpacts);
    learn->idle_timeout = OFP_FLOW_PERMANENT;
    learn->hard_timeout = OFP_FLOW_PERMANENT;
    learn->priority = OFP_DEFAULT_PRIORITY;
    learn->table_id = 1;

    match_init_catchall(&match);
    while (ofputil_parse_key_value(&arg, &name, &value)) {
        if (!strcmp(name, "table")) {
            learn->table_id = atoi(value);
            if (learn->table_id == 255) {
                return xasprintf("%s: table id 255 not valid for `learn' "
                                 "action", orig);
            }
        } else 
            ...
        } else {
            struct ofpact_learn_spec *spec;
            char *error;

            spec = ofpbuf_put_zeros(ofpacts, sizeof *spec);
            error = learn_parse_spec(orig, name, value, port_map,
                                     spec, ofpacts, &match);
            if (error) {
                return error;
            }
            learn = ofpacts->header;
        }
    }

static char * OVS_WARN_UNUSED_RESULT
learn_parse_spec(const char *orig, char *name, char *value,
                 const struct ofputil_port_map *port_map,
                 struct ofpact_learn_spec *spec,
                 struct ofpbuf *ofpacts, struct match *match)
    /* Parse destination and check prerequisites. */
    struct mf_subfield dst;

    char *error = mf_parse_subfield(&dst, name);
    bool parse_error = error != NULL;
    free(error);

    //只要parse_error为空,说明根据name查找到了field, 说明这是一个匹配域。action只会以 load 或者 output 开始
    if (!parse_error) {

    //load action
    } else if (!strcmp(name, "load")) {
    
    //output action
    } else if (!strcmp(name, "output")) {
    }

ovs-vswitchd端通过 xlate_learn_action 来生成流表,并添加到指定table中。

参考

https://docs.openvswitch.org/en/latest/tutorials/ovs-advanced/
https://man7.org/linux/man-pages/man7/ovs-actions.7.html
https://man7.org/linux/man-pages/man7/ovs-fields.7.html

也可参考:ovs learn action - 简书 (jianshu.com)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OVS offload 是指在开放式虚拟交换机(Open vSwitch,即OVS)中使用硬件加速来提升网络数据包处理的性能和效率。传统上,虚拟交换机在软件层面进行数据包处理,这可能会导致性能瓶颈和延迟增加。因此,为了解决这些问题,OVS offload 技术应运而生。 通过 OVS offload,虚拟交换机可以将一些网络数据包的处理任务委托给硬件设备来完成,而不是完全依赖于软件。这些硬件设备可以是物理网络交换机的芯片或网卡上的功能块,也可以是专门设计的网络加速卡(Network Interface Card,即NIC),具体取决于硬件厂商的支持。 OVS offload 技术带来了多方面的好处。首先,它可以大幅度提高网络数据包的处理速度和吞吐量,从而减少延迟并提供更好的网络性能。其次,它可以减轻CPU的负担,使其能够处理更多的网络流量和更复杂的网络任务。此外,OVS offload 还可以提供更好的网络流量监控和安全性,通过硬件加速可以更快速地检测和处理网络攻击。 然而,OVS offload 技术也存在一些限制。首先,它取决于硬件设备的支持,因此只有特定的硬件设备才能充分发挥其优势。其次,OVS offload 目前仍处于发展阶段,可能存在一些兼容性问题或性能优化的空间。因此,在实际应用中,需要仔细评估硬件设备的支持和兼容性,以及进行适当的性能测试和调优。 总的来说,OVS offload 技术为虚拟交换机提供了一种有效的性能优化手段,可以提高网络数据包处理的效率和性能。它在实际应用中具有广泛的应用前景,并且随着硬件技术的不断发展,其性能还将进一步提升。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值