Add a new ODP action and implements the corresponding Netlink message handling of this new attribute.
Signed-off-by: Andy Zhou <az...@nicira.com> --- datapath/linux/compat/include/linux/openvswitch.h | 29 +++++++++++++++++++- lib/dpif-netdev.c | 1 + lib/dpif.c | 1 + lib/odp-execute.c | 1 + lib/odp-util.c | 33 +++++++++++++++++++++++ 5 files changed, 64 insertions(+), 1 deletion(-) diff --git a/datapath/linux/compat/include/linux/openvswitch.h b/datapath/linux/compat/include/linux/openvswitch.h index a59e109..7284023 100644 --- a/datapath/linux/compat/include/linux/openvswitch.h +++ b/datapath/linux/compat/include/linux/openvswitch.h @@ -569,6 +569,18 @@ struct ovs_action_push_mpls { }; /** + * struct ovs_action_bpf_prog - %OVS_ACTION_ATTR_BPF_PROG action argument. + * + * XXX provides bpf program id and execution context. + * + */ +struct ovs_action_bpf_prog { + __be32 prog_fd; + __be32 arg0; + __be32 arg1; +}; + +/** * struct ovs_action_push_vlan - %OVS_ACTION_ATTR_PUSH_VLAN action argument. * @vlan_tpid: Tag protocol identifier (TPID) to push. * @vlan_tci: Tag control identifier (TCI) to push. The CFI bit must be set @@ -685,7 +697,7 @@ enum ovs_action_attr { * data immediately followed by a mask. * The data must be zero for the unmasked * bits. */ - + OVS_ACTION_ATTR_BPF_PROG, /* struct ovs_action_bpf_prog. */ #ifndef __KERNEL__ OVS_ACTION_ATTR_TUNNEL_PUSH, /* struct ovs_action_push_tnl*/ OVS_ACTION_ATTR_TUNNEL_POP, /* u32 port number. */ @@ -695,4 +707,19 @@ enum ovs_action_attr { #define OVS_ACTION_ATTR_MAX (__OVS_ACTION_ATTR_MAX - 1) +/* integer value in 'imm' field of BPF_CALL instruction selects which OVS helper + * function eBPF program intends to call + */ +enum ovs_bpf_func_id { + OVS_BPF_FUNC_unspec, + OVS_BPF_FUNC_output, /* int ovs_bpf_output(ctxt) */ + __OVS_BPF_FUNC_MAX_ID, +}; + +struct ovs_bpf_action_ctxt { + void *skb; + uint32_t arg0; + uint32_t arg1; +}; + #endif /* _LINUX_OPENVSWITCH_H */ diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 54bad02..e991716 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -3240,6 +3240,7 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt, case OVS_ACTION_ATTR_SAMPLE: case OVS_ACTION_ATTR_HASH: case OVS_ACTION_ATTR_UNSPEC: + case OVS_ACTION_ATTR_BPF_PROG: case __OVS_ACTION_ATTR_MAX: OVS_NOT_REACHED(); } diff --git a/lib/dpif.c b/lib/dpif.c index 6ecd1d9..8aac7dd 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1132,6 +1132,7 @@ dpif_execute_helper_cb(void *aux_, struct dpif_packet **packets, int cnt, case OVS_ACTION_ATTR_SET_MASKED: case OVS_ACTION_ATTR_SAMPLE: case OVS_ACTION_ATTR_UNSPEC: + case OVS_ACTION_ATTR_BPF_PROG: case __OVS_ACTION_ATTR_MAX: OVS_NOT_REACHED(); } diff --git a/lib/odp-execute.c b/lib/odp-execute.c index 98ac18c..ee06362 100644 --- a/lib/odp-execute.c +++ b/lib/odp-execute.c @@ -591,6 +591,7 @@ odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt, bool steal, break; case OVS_ACTION_ATTR_UNSPEC: + case OVS_ACTION_ATTR_BPF_PROG: case __OVS_ACTION_ATTR_MAX: OVS_NOT_REACHED(); } diff --git a/lib/odp-util.c b/lib/odp-util.c index 37d73a9..1477d13 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -88,6 +88,7 @@ odp_action_len(uint16_t type) case OVS_ACTION_ATTR_SET: return -2; case OVS_ACTION_ATTR_SET_MASKED: return -2; case OVS_ACTION_ATTR_SAMPLE: return -2; + case OVS_ACTION_ATTR_BPF_PROG: return sizeof(struct ovs_action_bpf_prog); case OVS_ACTION_ATTR_UNSPEC: case __OVS_ACTION_ATTR_MAX: @@ -185,6 +186,17 @@ format_odp_sample_action(struct ds *ds, const struct nlattr *attr) ds_put_format(ds, "))"); } +static void +format_bpf_prog_action(struct ds *ds, const struct nlattr *a) +{ + struct ovs_action_bpf_prog *bpf_act = (struct ovs_action_bpf_prog *) + nl_attr_get(a); + + ds_put_cstr(ds, "bpf"); + ds_put_format(ds, "(%u,%u,%u)", ntohl(bpf_act->prog_fd), + ntohl(bpf_act->arg0), ntohl(bpf_act->arg1)); +} + static const char * slow_path_reason_to_string(uint32_t reason) { @@ -682,6 +694,9 @@ format_odp_action(struct ds *ds, const struct nlattr *a) case OVS_ACTION_ATTR_SAMPLE: format_odp_sample_action(ds, a); break; + case OVS_ACTION_ATTR_BPF_PROG: + format_bpf_prog_action(ds, a); + break; case OVS_ACTION_ATTR_UNSPEC: case __OVS_ACTION_ATTR_MAX: default: @@ -1006,6 +1021,24 @@ parse_odp_action(const char *s, const struct simap *port_names, return parse_odp_userspace_action(s, actions); } + { + struct ovs_action_bpf_prog act_bpf; + uint32_t fd; + uint32_t arg0, arg1; + int n = -1; + + if (ovs_scan(s, "bpf(%"PRIu32",%"PRIu32",%"PRIu32")%n", &fd, &arg0, + &arg1, &n)) { + memset(&act_bpf, 0, sizeof(act_bpf)); + act_bpf.prog_fd = htonl(fd); + act_bpf.arg0 = htonl(arg0); + act_bpf.arg1 = htonl(arg1); + nl_msg_put_unspec(actions, OVS_ACTION_ATTR_BPF_PROG, + &act_bpf, sizeof(act_bpf)); + return n; + } + } + if (!strncmp(s, "set(", 4)) { size_t start_ofs; int retval; -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev