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

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