@@ -8469,6 +8469,7 @@ const struct dpif_class dpif_netdev_class = {
dpif_netdev_register_upcall_cb,
dpif_netdev_enable_upcall,
dpif_netdev_disable_upcall,
+ NULL, /* register_sflow_upcall_cb */
dpif_netdev_get_datapath_version,
dpif_netdev_ct_dump_start,
dpif_netdev_ct_dump_next,
@@ -3983,6 +3983,7 @@ const struct dpif_class dpif_netlink_class = {
NULL, /* register_upcall_cb */
NULL, /* enable_upcall */
NULL, /* disable_upcall */
+ NULL, /* register_sflow_upcall_cb */
dpif_netlink_get_datapath_version, /* get_datapath_version */
dpif_netlink_ct_dump_start,
dpif_netlink_ct_dump_next,
@@ -427,6 +427,16 @@ struct dpif_class {
/* Disables upcalls if 'dpif' directly executes upcall functions. */
void (*disable_upcall)(struct dpif *);
+ /* When offloading sample action, psample sends the sampled packets to
+ * userspace by a netlink message. The thread polling psample socket
+ * will translate the psample netlink message to an sFlow format and call
+ * the sFlow upcall callback to send the sFlow packet to right monitoring
+ * host.
+ *
+ * Registers an upcall callback to process sFlow packet.
+ */
+ void (*register_sflow_upcall_cb)(struct dpif *, sflow_upcall_callback *);
+
/* Get datapath version. Caller is responsible for freeing the string
* returned. */
char *(*get_datapath_version)(void);
@@ -1520,6 +1520,14 @@ dpif_disable_upcall(struct dpif *dpif)
}
}
+void
+dpif_register_sflow_upcall_cb(struct dpif *dpif, sflow_upcall_callback *cb)
+{
+ if (dpif->dpif_class->register_sflow_upcall_cb) {
+ dpif->dpif_class->register_sflow_upcall_cb(dpif, cb);
+ }
+}
+
void
dpif_print_packet(struct dpif *dpif, struct dpif_upcall *upcall)
{
@@ -871,6 +871,29 @@ typedef int upcall_callback(const struct dp_packet *packet,
void dpif_register_upcall_cb(struct dpif *, upcall_callback *, void *aux);
+/* When offloading sample action, userspace creates a unique ID to map
+ * sFlow action and tunnel info and passes this ID to datapath instead
+ * of the sFlow info. Datapath will send this ID and sampled packet to
+ * userspace. Using the ID, userspace can recover the sFlow info and send
+ * sampled packet to the right sFlow monitoring host.
+ */
+struct dpif_sflow_attr {
+ const struct nlattr *sflow; /* sFlow action */
+ void *userdata; /* struct user_action_cookie */
+ size_t userdata_len; /* struct user_action_cookie length */
+ struct flow_tnl *tunnel; /* Tunnel info */
+};
+
+/* A sampled packet passed up from datapath to userspace. */
+struct dpif_upcall_sflow {
+ struct dp_packet packet; /* packet data */
+ uint32_t iifindex; /* input ifindex */
+ const struct dpif_sflow_attr *sflow_attr;
+};
+
+typedef int sflow_upcall_callback(struct dpif_upcall_sflow *dupcall);
+void dpif_register_sflow_upcall_cb(struct dpif *, sflow_upcall_callback *);
+
int dpif_recv_set(struct dpif *, bool enable);
int dpif_handlers_set(struct dpif *, uint32_t n_handlers);
int dpif_set_config(struct dpif *, const struct smap *cfg);