Openvswitch原理与代码分析(8): 修改Openvswitch代码添加自定义action

有时候我们需要自定义一些自己的action,根据包头里面的信息,做一些自己的操作。

 

例如添加一个action名为handle_example

 

第一、修改ofp-actions.c文件

 

首先在ofp-actions.c里面添加Openflow各个版本的这个action

  1. static const struct ofpact_map *
  2. get_ofpact_map(enum ofp_version version)
  3. {
  4.     /* OpenFlow 1.0 actions. */
  5.     static const struct ofpact_map of10[] = {
  6.         { OFPACT_OUTPUT, 0 },
  7.         { OFPACT_SET_VLAN_VID, 1 },
  8.         { OFPACT_SET_VLAN_PCP, 2 },
  9.         { OFPACT_STRIP_VLAN, 3 },
  10.         { OFPACT_SET_ETH_SRC, 4 },
  11.         { OFPACT_SET_ETH_DST, 5 },
  12.         { OFPACT_SET_IPV4_SRC, 6 },
  13.         { OFPACT_SET_IPV4_DST, 7 },
  14.         { OFPACT_SET_IP_DSCP, 8 },
  15.         { OFPACT_SET_L4_SRC_PORT, 9 },
  16.         { OFPACT_SET_L4_DST_PORT, 10 },
  17.         { OFPACT_ENQUEUE, 11 },
  18.         { OFPACT_HANDLE_EXAMPLE, 28 },
  19.         { 0, -1 },
  20.     };
  21.  
  22.     /* OpenFlow 1.1 actions. */
  23.     static const struct ofpact_map of11[] = {
  24.         { OFPACT_OUTPUT, 0 },
  25.         { OFPACT_SET_VLAN_VID, 1 },
  26.         { OFPACT_SET_VLAN_PCP, 2 },
  27.         { OFPACT_SET_ETH_SRC, 3 },
  28.         { OFPACT_SET_ETH_DST, 4 },
  29.         { OFPACT_SET_IPV4_SRC, 5 },
  30.         { OFPACT_SET_IPV4_DST, 6 },
  31.         { OFPACT_SET_IP_DSCP, 7 },
  32.         { OFPACT_SET_IP_ECN, 8 },
  33.         { OFPACT_SET_L4_SRC_PORT, 9 },
  34.         { OFPACT_SET_L4_DST_PORT, 10 },
  35.         /* OFPAT_COPY_TTL_OUT (11) not supported. */
  36.         /* OFPAT_COPY_TTL_IN (12) not supported. */
  37.         { OFPACT_SET_MPLS_LABEL, 13 },
  38.         { OFPACT_SET_MPLS_TC, 14 },
  39.         { OFPACT_SET_MPLS_TTL, 15 },
  40.         { OFPACT_DEC_MPLS_TTL, 16 },
  41.         { OFPACT_PUSH_VLAN, 17 },
  42.         { OFPACT_STRIP_VLAN, 18 },
  43.         { OFPACT_PUSH_MPLS, 19 },
  44.         { OFPACT_POP_MPLS, 20 },
  45.         { OFPACT_SET_QUEUE, 21 },
  46.         { OFPACT_GROUP, 22 },
  47.         { OFPACT_SET_IP_TTL, 23 },
  48.         { OFPACT_DEC_TTL, 24 },
  49.         { OFPACT_HANDLE_EXAMPLE, 28 },
  50.         { 0, -1 },
  51.     };
  52.  
  53.     /* OpenFlow 1.2, 1.3, and 1.4 actions. */
  54.     static const struct ofpact_map of12[] = {
  55.         { OFPACT_OUTPUT, 0 },
  56.         /* OFPAT_COPY_TTL_OUT (11) not supported. */
  57.         /* OFPAT_COPY_TTL_IN (12) not supported. */
  58.         { OFPACT_SET_MPLS_TTL, 15 },
  59.         { OFPACT_DEC_MPLS_TTL, 16 },
  60.         { OFPACT_PUSH_VLAN, 17 },
  61.         { OFPACT_STRIP_VLAN, 18 },
  62.         { OFPACT_PUSH_MPLS, 19 },
  63.         { OFPACT_POP_MPLS, 20 },
  64.         { OFPACT_SET_QUEUE, 21 },
  65.         { OFPACT_GROUP, 22 },
  66.         { OFPACT_SET_IP_TTL, 23 },
  67.         { OFPACT_DEC_TTL, 24 },
  68.         { OFPACT_SET_FIELD, 25 },
  69.         /* OF1.3+ OFPAT_PUSH_PBB (26) not supported. */
  70.         /* OF1.3+ OFPAT_POP_PBB (27) not supported. */
  71.         { OFPACT_HANDLE_EXAMPLE, 28 },
  72.         { 0, -1 },
  73.     };
  74.  
  75.     switch (version) {
  76.     case OFP10_VERSION:
  77.         return of10;
  78.  
  79.     case OFP11_VERSION:
  80.         return of11;
  81.  
  82.     case OFP12_VERSION:
  83.     case OFP13_VERSION:
  84.     case OFP14_VERSION:
  85.     case OFP15_VERSION:
  86.     default:
  87.         return of12;
  88.     }
  89. }

 

其次添加raw action type

  1. enum ofp_raw_action_type {
  2. /* ## ----------------- ## */
  3. /* ## Standard actions. ## */
  4. /* ## ----------------- ## */
  5.  
  6.     /* OF1.0(0): struct ofp10_action_output. */
  7.     OFPAT_RAW10_OUTPUT,
  8.     /* OF1.1+(0): struct ofp11_action_output. */
  9.     OFPAT_RAW11_OUTPUT,
  10.  
  11.     /* OF1.0(1): uint16_t. */
  12.     OFPAT_RAW10_SET_VLAN_VID,
  13.     /* OF1.0(2): uint8_t. */
  14.     OFPAT_RAW10_SET_VLAN_PCP,
  15.  
  16.     /* OF1.1(1), OF1.2+(1) is deprecated (use Set-Field): uint16_t.
  17.      *
  18.      * [Semantics differ slightly between the 1.0 and 1.1 versions of the VLAN
  19.      * modification actions: the 1.0 versions push a VLAN header if none is
  20.      * present, but the 1.1 versions do not. That is the only reason that we
  21.      * distinguish their raw action types.] */
  22.     OFPAT_RAW11_SET_VLAN_VID,
  23.     /* OF1.1(2), OF1.2+(2) is deprecated (use Set-Field): uint8_t. */
  24.     OFPAT_RAW11_SET_VLAN_PCP,
  25.  
  26.     /* OF1.1+(17): ovs_be16.
  27.      *
  28.      * [The argument is the Ethertype, e.g. ETH_TYPE_VLAN_8021Q, not the VID or
  29.      * TCI.] */
  30.     OFPAT_RAW11_PUSH_VLAN,
  31.  
  32.     /* OF1.0(3): void. */
  33.     OFPAT_RAW10_STRIP_VLAN,
  34.     /* OF1.1+(18): void. */
  35.     OFPAT_RAW11_POP_VLAN,
  36.  
  37.     /* OF1.0(4), OF1.1(3), OF1.2+(3) is deprecated (use Set-Field): struct
  38.      * ofp_action_dl_addr. */
  39.     OFPAT_RAW_SET_DL_SRC,
  40.  
  41.     /* OF1.0(5), OF1.1(4), OF1.2+(4) is deprecated (use Set-Field): struct
  42.      * ofp_action_dl_addr. */
  43.     OFPAT_RAW_SET_DL_DST,
  44.  
  45.     /* OF1.0(6), OF1.1(5), OF1.2+(5) is deprecated (use Set-Field):
  46.      * ovs_be32. */
  47.     OFPAT_RAW_SET_NW_SRC,
  48.  
  49.     /* OF1.0(7), OF1.1(6), OF1.2+(6) is deprecated (use Set-Field):
  50.      * ovs_be32. */
  51.     OFPAT_RAW_SET_NW_DST,
  52.  
  53.     /* OF1.0(8), OF1.1(7), OF1.2+(7) is deprecated (use Set-Field): uint8_t. */
  54.     OFPAT_RAW_SET_NW_TOS,
  55.  
  56.     /* OF1.1(8), OF1.2+(8) is deprecated (use Set-Field): uint8_t. */
  57.     OFPAT_RAW11_SET_NW_ECN,
  58.  
  59.     /* OF1.0(9), OF1.1(9), OF1.2+(9) is deprecated (use Set-Field):
  60.      * ovs_be16. */
  61.     OFPAT_RAW_SET_TP_SRC,
  62.  
  63.     /* OF1.0(10), OF1.1(10), OF1.2+(10) is deprecated (use Set-Field):
  64.      * ovs_be16. */
  65.     OFPAT_RAW_SET_TP_DST,
  66.  
  67.     /* OF1.0(11): struct ofp10_action_enqueue. */
  68.     OFPAT_RAW10_ENQUEUE,
  69.  
  70.     /* NX1.0(30), OF1.1(13), OF1.2+(13) is deprecated (use Set-Field):
  71.      * ovs_be32. */
  72.     OFPAT_RAW_SET_MPLS_LABEL,
  73.  
  74.     /* NX1.0(31), OF1.1(14), OF1.2+(14) is deprecated (use Set-Field):
  75.      * uint8_t. */
  76.     OFPAT_RAW_SET_MPLS_TC,
  77.  
  78.     /* NX1.0(25), OF1.1(15), OF1.2+(15) is deprecated (use Set-Field):
  79.      * uint8_t. */
  80.     OFPAT_RAW_SET_MPLS_TTL,
  81.  
  82.     /* NX1.0(26), OF1.1+(16): void. */
  83.     OFPAT_RAW_DEC_MPLS_TTL,
  84.  
  85.     /* NX1.0(23), OF1.1+(19): ovs_be16.
  86.      *
  87.      * [The argument is the Ethertype, e.g. ETH_TYPE_MPLS, not the label.] */
  88.     OFPAT_RAW_PUSH_MPLS,
  89.  
  90.     /* NX1.0(24), OF1.1+(20): ovs_be16.
  91.      *
  92.      * [The argument is the Ethertype, e.g. ETH_TYPE_IPV4 if at BoS or
  93.      * ETH_TYPE_MPLS otherwise, not the label.] */
  94.     OFPAT_RAW_POP_MPLS,
  95.  
  96.     /* NX1.0(4), OF1.1+(21): uint32_t. */
  97.     OFPAT_RAW_SET_QUEUE,
  98.  
  99.     /* OF1.1+(22): uint32_t. */
  100.     OFPAT_RAW11_GROUP,
  101.  
  102.     /* OF1.1+(23): uint8_t. */
  103.     OFPAT_RAW11_SET_NW_TTL,
  104.  
  105.     /* NX1.0(18), OF1.1+(24): void. */
  106.     OFPAT_RAW_DEC_NW_TTL,
  107.     /* NX1.0+(21): struct nx_action_cnt_ids, ... */
  108.     NXAST_RAW_DEC_TTL_CNT_IDS,
  109.  
  110.     /* OF1.2-1.4(25): struct ofp12_action_set_field, ... */
  111.     OFPAT_RAW12_SET_FIELD,
  112.     /* OF1.5+(25): struct ofp12_action_set_field, ... */
  113.     OFPAT_RAW15_SET_FIELD,
  114.  
  115.     /* OF1.0(28): void. */
  116.     OFPAT_RAW10_HANDLE_EXAMPLE,
  117.  
  118.     /* OF1.1(28): void. */
  119.     OFPAT_RAW11_HANDLE_EXAMPLE,
  120.  
  121.     /* OF1.2-1.4(28): void. */
  122.     OFPAT_RAW12_HANDLE_EXAMPLE,
  123.  
  124.     /* NX1.0-1.4(7): struct nx_action_reg_load.
  125.      *
  126.      * [In OpenFlow 1.5, set_field is a superset of reg_load functionality, so
  127.      * we drop reg_load.] */
  128.     NXAST_RAW_REG_LOAD,
  129.     /* NX1.0-1.4(33): struct nx_action_reg_load2, ...
  130.      *
  131.      * [In OpenFlow 1.5, set_field is a superset of reg_load2 functionality, so
  132.      * we drop reg_load2.] */
  133.     NXAST_RAW_REG_LOAD2,
  134.  
  135.     /* OF1.5+(28): struct ofp15_action_copy_field, ... */
  136.     OFPAT_RAW15_COPY_FIELD,
  137.     /* ONF1.3-1.4(3200): struct onf_action_copy_field, ... */
  138.     ONFACT_RAW13_COPY_FIELD,
  139.     /* NX1.0-1.4(6): struct nx_action_reg_move, ... */
  140.     NXAST_RAW_REG_MOVE,
  141.  
  142. /* ## ------------------------- ## */
  143. /* ## Nicira extension actions. ## */
  144. /* ## ------------------------- ## */
  145.  
  146. /* Actions similar to standard actions are listed with the standard actions. */
  147.  
  148.     /* NX1.0+(1): uint16_t. */
  149.     NXAST_RAW_RESUBMIT,
  150.     /* NX1.0+(14): struct nx_action_resubmit. */
  151.     NXAST_RAW_RESUBMIT_TABLE,
  152.  
  153.     /* NX1.0+(2): uint32_t. */
  154.     NXAST_RAW_SET_TUNNEL,
  155.     /* NX1.0+(9): uint64_t. */
  156.     NXAST_RAW_SET_TUNNEL64,
  157.  
  158.     /* NX1.0+(5): void. */
  159.     NXAST_RAW_POP_QUEUE,
  160.  
  161.     /* NX1.0+(8): struct nx_action_note, ... */
  162.     NXAST_RAW_NOTE,
  163.  
  164.     /* NX1.0+(10): struct nx_action_multipath. */
  165.     NXAST_RAW_MULTIPATH,
  166.  
  167.     /* NX1.0+(12): struct nx_action_bundle, ... */
  168.     NXAST_RAW_BUNDLE,
  169.     /* NX1.0+(13): struct nx_action_bundle, ... */
  170.     NXAST_RAW_BUNDLE_LOAD,
  171.  
  172.     /* NX1.0+(15): struct nx_action_output_reg. */
  173.     NXAST_RAW_OUTPUT_REG,
  174.     /* NX1.0+(32): struct nx_action_output_reg2. */
  175.     NXAST_RAW_OUTPUT_REG2,
  176.  
  177.     /* NX1.0+(16): struct nx_action_learn, ... */
  178.     NXAST_RAW_LEARN,
  179.  
  180.     /* NX1.0+(17): void. */
  181.     NXAST_RAW_EXIT,
  182.  
  183.     /* NX1.0+(19): struct nx_action_fin_timeout. */
  184.     NXAST_RAW_FIN_TIMEOUT,
  185.  
  186.     /* NX1.0+(20): struct nx_action_controller. */
  187.     NXAST_RAW_CONTROLLER,
  188.  
  189.     /* NX1.0+(22): struct nx_action_write_metadata. */
  190.     NXAST_RAW_WRITE_METADATA,
  191.  
  192.     /* NX1.0+(27): struct nx_action_stack. */
  193.     NXAST_RAW_STACK_PUSH,
  194.  
  195.     /* NX1.0+(28): struct nx_action_stack. */
  196.     NXAST_RAW_STACK_POP,
  197.  
  198.     /* NX1.0+(29): struct nx_action_sample. */
  199.     NXAST_RAW_SAMPLE,
  200.  
  201.     /* NX1.0+(34): struct nx_action_conjunction. */
  202.     NXAST_RAW_CONJUNCTION,
  203.  
  204.     /* NX1.0+(35): struct nx_action_conntrack, ... */
  205.     NXAST_RAW_CT,
  206.  
  207. /* ## ------------------ ## */
  208. /* ## Debugging actions. ## */
  209. /* ## ------------------ ## */
  210.  
  211. /* These are intentionally undocumented, subject to change, and ovs-vswitchd */
  212. /* accepts them only if started with --enable-dummy. */
  213.  
  214.     /* NX1.0+(255): void. */
  215.     NXAST_RAW_DEBUG_RECIRC,
  216. };

 

第三,添加handle example的action的处理函数

  1. /* handle gtp actions. */
  2. static enum ofperr
  3. decode_OFPAT_RAW10_HANDLE_EXAMPLE(struct ofpbuf *out)
  4. {
  5.     ofpact_put_HANDLE_EXAMPLE(out)->ofpact.raw = OFPAT_RAW10_HANDLE_EXAMPLE;
  6.     return 0;
  7. }
  8.  
  9. static enum ofperr
  10. decode_OFPAT_RAW11_HANDLE_EXAMPLE(struct ofpbuf *out)
  11. {
  12.     ofpact_put_HANDLE_EXAMPLE(out)->ofpact.raw = OFPAT_RAW11_HANDLE_EXAMPLE;
  13.     return 0;
  14. }
  15.  
  16. static enum ofperr
  17. decode_OFPAT_RAW12_HANDLE_EXAMPLE(struct ofpbuf *out)
  18. {
  19.     ofpact_put_HANDLE_EXAMPLE(out)->ofpact.raw = OFPAT_RAW12_HANDLE_EXAMPLE;
  20.     return 0;
  21. }
  22.  
  23. static void
  24. encode_HANDLE_EXAMPLE(const struct ofpact_null *null OVS_UNUSED,
  25.                   enum ofp_version ofp_version, struct ofpbuf *out)
  26. {
  27.     if (ofp_version == OFP10_VERSION) {
  28.         put_OFPAT10_HANDLE_EXAMPLE(out);
  29.     } else if (ofp_version == OFP11_VERSION) {
  30.         put_OFPAT11_HANDLE_EXAMPLE(out);
  31.     } else {
  32.         put_OFPAT12_HANDLE_EXAMPLE(out);
  33.     }
  34. }
  35.  
  36. static char * OVS_WARN_UNUSED_RESULT
  37. parse_HANDLE_EXAMPLE(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
  38.                  enum ofputil_protocol *usable_protocols OVS_UNUSED)
  39. {
  40.     ofpact_put_HANDLE_EXAMPLE(ofpacts)->ofpact.raw = OFPAT_RAW10_HANDLE_EXAMPLE;
  41.     return NULL;
  42. }
  43.  
  44. static void
  45. format_HANDLE_EXAMPLE(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
  46. {
  47.     ds_put_cstr(s, "handle_example");
  48. }

 

  1. struct ofpact *
  2. ofpact_next_flattened(const struct ofpact *ofpact)
  3. {
  4. switch (ofpact->type) {
  5. case OFPACT_HANDLE_EXAMPLE:

 

  1. static bool
  2. ofpact_is_set_or_move_action(const struct ofpact *a)
  3. {
  4.     switch (a->type) {
  5.     case OFPACT_HANDLE_EXAMPLE:
  6. return true;

 

  1. static bool
  2. ofpact_is_allowed_in_actions_set(const struct ofpact *a)
  3. {
  4.     switch (a->type) {
  5.     case OFPACT_HANDLE_EXAMPLE:
  6. return true;

 

  1. enum ovs_instruction_type
  2. ovs_instruction_type_from_ofpact_type(enum ofpact_type type)
  3. {
  4.     switch (type) {
  5.     case OFPACT_HANDLE_EXAMPLE:

 

  1. static enum ofperr
  2. ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
  3.                struct flow *flow, ofp_port_t max_ports,
  4.                uint8_t table_id, uint8_t n_tables)
  5. {
  6.     const struct ofpact_enqueue *enqueue;
  7.     const struct mf_field *mf;
  8.  
  9.     switch (a->type) {
  10.     case OFPACT_HANDLE_EXAMPLE:
  11.         return 0;

 

  1. static bool
  2. ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
  3. {
  4.     switch (ofpact->type) {
  5.     case OFPACT_HANDLE_EXAMPLE:
  6.     default:
  7.         return false;

 

第二,修改文件ofp-actions.h

 

  1. #define OFPACTS \
  2.     /* Output. */ \
  3.     OFPACT(OUTPUT, ofpact_output, ofpact, "output") \
  4.     OFPACT(GROUP, ofpact_group, ofpact, "group") \
  5.     OFPACT(CONTROLLER, ofpact_controller, ofpact, "controller") \
  6.     OFPACT(ENQUEUE, ofpact_enqueue, ofpact, "enqueue") \
  7.     OFPACT(OUTPUT_REG, ofpact_output_reg, ofpact, "output_reg") \
  8.     OFPACT(BUNDLE, ofpact_bundle, slaves, "bundle") \
  9.                                                                         \
  10.     /* Header changes. */ \
  11.     OFPACT(SET_FIELD, ofpact_set_field, ofpact, "set_field") \
  12.     OFPACT(HANDLE_EXAMPLE, ofpact_null, ofpact, "handle_example") \
  13.     OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact, "set_vlan_vid") \
  14.     OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact, "set_vlan_pcp") \
  15.     OFPACT(STRIP_VLAN, ofpact_null, ofpact, "strip_vlan") \
  16.     OFPACT(PUSH_VLAN, ofpact_null, ofpact, "push_vlan") \
  17.     OFPACT(SET_ETH_SRC, ofpact_mac, ofpact, "mod_dl_src") \
  18.     OFPACT(SET_ETH_DST, ofpact_mac, ofpact, "mod_dl_dst") \
  19.     OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact, "mod_nw_src") \
  20.     OFPACT(SET_IPV4_DST, ofpact_ipv4, ofpact, "mod_nw_dst") \
  21.     OFPACT(SET_IP_DSCP, ofpact_dscp, ofpact, "mod_nw_tos") \
  22.     OFPACT(SET_IP_ECN, ofpact_ecn, ofpact, "mod_nw_ecn") \
  23.     OFPACT(SET_IP_TTL, ofpact_ip_ttl, ofpact, "mod_nw_ttl") \
  24.     OFPACT(SET_L4_SRC_PORT, ofpact_l4_port, ofpact, "mod_tp_src") \
  25.     OFPACT(SET_L4_DST_PORT, ofpact_l4_port, ofpact, "mod_tp_dst") \
  26.     OFPACT(REG_MOVE, ofpact_reg_move, ofpact, "move") \
  27.     OFPACT(STACK_PUSH, ofpact_stack, ofpact, "push") \
  28.     OFPACT(STACK_POP, ofpact_stack, ofpact, "pop") \
  29.     OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids, "dec_ttl") \
  30.     OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact, "set_mpls_label") \
  31.     OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact, "set_mpls_tc") \
  32.     OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact, "set_mpls_ttl") \
  33.     OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact, "dec_mpls_ttl") \
  34.     OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact, "push_mpls") \
  35.     OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact, "pop_mpls") \
  36.                                                                         \
  37.     /* Metadata. */ \
  38.     OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact, "set_tunnel") \
  39.     OFPACT(SET_QUEUE, ofpact_queue, ofpact, "set_queue") \
  40.     OFPACT(POP_QUEUE, ofpact_null, ofpact, "pop_queue") \
  41.     OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact, "fin_timeout") \
  42.                                                                         \
  43.     /* Flow table interaction. */ \
  44.     OFPACT(RESUBMIT, ofpact_resubmit, ofpact, "resubmit") \
  45.     OFPACT(LEARN, ofpact_learn, specs, "learn") \
  46.     OFPACT(CONJUNCTION, ofpact_conjunction, ofpact, "conjunction") \
  47.                                                                         \
  48.     /* Arithmetic. */ \
  49.     OFPACT(MULTIPATH, ofpact_multipath, ofpact, "multipath") \
  50.                                                                         \
  51.     /* Other. */ \
  52.     OFPACT(NOTE, ofpact_note, data, "note") \
  53.     OFPACT(EXIT, ofpact_null, ofpact, "exit") \
  54.     OFPACT(SAMPLE, ofpact_sample, ofpact, "sample") \
  55.     OFPACT(UNROLL_XLATE, ofpact_unroll_xlate, ofpact, "unroll_xlate") \
  56.     OFPACT(CT, ofpact_conntrack, ofpact, "ct") \
  57.                                                                         \
  58.     /* Debugging actions. \
  59.      * \
  60.      * These are intentionally undocumented, subject to change, and \
  61.      * only accepted if ovs-vswitchd is started with --enable-dummy. */ \
  62.     OFPACT(DEBUG_RECIRC, ofpact_null, ofpact, "debug_recirc") \
  63.                                                                         \
  64.     /* Instructions. */ \
  65.     OFPACT(METER, ofpact_meter, ofpact, "meter") \
  66.     OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact, "clear_actions") \
  67.     OFPACT(WRITE_ACTIONS, ofpact_nest, ofpact, "write_actions") \
  68.     OFPACT(WRITE_METADATA, ofpact_metadata, ofpact, "write_metadata") \
  69.     OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact, "goto_table")

 

第三、修改ofproto\ofproto-dpif-xlate.c文件

 

  1. static void
  2. recirc_unroll_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
  3.                       struct xlate_ctx *ctx)
  4. {
  5.     const struct ofpact *a;
  6.  
  7.     OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
  8.         switch (a->type) {
  9.         case OFPACT_OPERATE_EXAMPLE:
  10.             /* These may not generate PACKET INs. */
  11.             break;

 

  1. static void
  2. do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
  3.                  struct xlate_ctx *ctx)
  4. {
  5.     struct flow_wildcards *wc = ctx->wc;
  6.     struct flow *flow = &ctx->xin->flow;
  7.     const struct ofpact *a;
  8.  
  9.     if (ovs_native_tunneling_is_on(ctx->xbridge->ofproto)) {
  10.         tnl_neigh_snoop(flow, wc, ctx->xbridge->name);
  11.     }
  12.     /* dl_type already in the mask, not set below. */
  13.  
  14.     OFPACT_FOR_EACH (a, ofpacts, ofpacts_len) {
  15.         struct ofpact_controller *controller;
  16.         const struct ofpact_metadata *metadata;
  17.         const struct ofpact_set_field *set_field;
  18.         const struct mf_field *mf;
  19.  
  20.         if (ctx->error) {
  21.             break;
  22.         }
  23.  
  24.         if (ctx->exit) {
  25.             /* Check if need to store the remaining actions for later
  26.              * execution. */
  27.             if (exit_recirculates(ctx)) {
  28.                 recirc_unroll_actions(a, OFPACT_ALIGN(ofpacts_len -
  29.                                                       ((uint8_t *)a -
  30.                                                        (uint8_t *)ofpacts)),
  31.                                       ctx);
  32.             }
  33.             break;
  34.         }
  35.  
  36.         switch (a->type) {
  37.    case OFPACT_HANDLE_EXAMPLE:
  38.             VLOG_INFO("OFPACT_HANDLE_EXAMPLE");
  39.             CHECK_MPLS_RECIRCULATION();
  40.             handle_example(flow, wc, ctx->xin->packet, ctx);
  41.             break;

 

最最重要的就是handle_example的实现,为你自己实现的逻辑,对于包头的修改可以通过修改flow来进行,也可以进一步解析ctx->xin->packet,也即解析网络包的正文。

你可能感兴趣的:(Openvswitch原理与代码分析(8): 修改Openvswitch代码添加自定义action)