Topics

[RFC PATCH 08/11] vswitch/bridge.c: add bpf datapath initialization.

William Tu
 

The patch initializes the bpf datapath when bridge starts.
The check_support could be avoided since we know what datapath
bpf program supports what feature.

Signed-off-by: Joe Stringer <joe@...>
Signed-off-by: William Tu <u9012063@...>
Signed-off-by: Yifeng Sun <pkusunyifeng@...>
Co-authored-by: William Tu <u9012063@...>
Co-authored-by: Yifeng Sun <pkusunyifeng@...>
---
lib/packets.h | 6 ++++-
ofproto/ofproto-dpif.c | 69 ++++++++++++++++++++++++++++++++++----------------
vswitchd/bridge.c | 21 +++++++++++++++
3 files changed, 73 insertions(+), 23 deletions(-)

diff --git a/lib/packets.h b/lib/packets.h
index 9a71aa3abbdb..2379c8f6d19d 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -47,7 +47,8 @@ static inline bool ipv6_addr_is_set(const struct in6_addr *addr);
static inline bool
flow_tnl_dst_is_set(const struct flow_tnl *tnl)
{
- return tnl->ip_dst || ipv6_addr_is_set(&tnl->ipv6_dst);
+ return tnl->ip_dst || ipv6_addr_is_set(&tnl->ipv6_dst) ||
+ tnl->ip_src || ipv6_addr_is_set(&tnl->ipv6_src);
}

struct in6_addr flow_tnl_dst(const struct flow_tnl *tnl);
@@ -154,7 +155,10 @@ pkt_metadata_init(struct pkt_metadata *md, odp_port_t port)
* we can just zero out ip_dst and the rest of the data will never be
* looked at. */
md->tunnel.ip_dst = 0;
+ md->tunnel.ip_src = 0;
md->tunnel.ipv6_dst = in6addr_any;
+ md->tunnel.ipv6_src = in6addr_any;
+
md->in_port.odp_port = port;
}

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 3365d4185926..115c138505ac 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1338,28 +1338,53 @@ CHECK_FEATURE__(ct_orig_tuple6, ct_orig_tuple6, ct_nw_proto, 1, ETH_TYPE_IPV6)
static void
check_support(struct dpif_backer *backer)
{
- /* Actions. */
- backer->rt_support.odp.recirc = check_recirc(backer);
- backer->rt_support.odp.max_vlan_headers = check_max_vlan_headers(backer);
- backer->rt_support.odp.max_mpls_depth = check_max_mpls_depth(backer);
- backer->rt_support.masked_set_action = check_masked_set_action(backer);
- backer->rt_support.trunc = check_trunc_action(backer);
- backer->rt_support.ufid = check_ufid(backer);
- backer->rt_support.tnl_push_pop = dpif_supports_tnl_push_pop(backer->dpif);
- backer->rt_support.clone = check_clone(backer);
- backer->rt_support.sample_nesting = check_max_sample_nesting(backer);
- backer->rt_support.ct_eventmask = check_ct_eventmask(backer);
- backer->rt_support.ct_clear = check_ct_clear(backer);
-
- /* Flow fields. */
- backer->rt_support.odp.ct_state = check_ct_state(backer);
- backer->rt_support.odp.ct_zone = check_ct_zone(backer);
- backer->rt_support.odp.ct_mark = check_ct_mark(backer);
- backer->rt_support.odp.ct_label = check_ct_label(backer);
-
- backer->rt_support.odp.ct_state_nat = check_ct_state_nat(backer);
- backer->rt_support.odp.ct_orig_tuple = check_ct_orig_tuple(backer);
- backer->rt_support.odp.ct_orig_tuple6 = check_ct_orig_tuple6(backer);
+ if (!strcmp(backer->type, "bpf")) {
+ /* Actions. */
+ backer->rt_support.odp.recirc = check_recirc(backer);
+ backer->rt_support.odp.max_vlan_headers = check_max_vlan_headers(backer);
+ backer->rt_support.odp.max_mpls_depth = check_max_mpls_depth(backer);
+ backer->rt_support.masked_set_action = check_masked_set_action(backer);
+ backer->rt_support.trunc = check_trunc_action(backer);
+ backer->rt_support.ufid = check_ufid(backer);
+ backer->rt_support.tnl_push_pop = dpif_supports_tnl_push_pop(backer->dpif);
+ backer->rt_support.clone = check_clone(backer);
+ backer->rt_support.sample_nesting = check_max_sample_nesting(backer);
+ backer->rt_support.ct_eventmask = false;
+ backer->rt_support.ct_clear = false;
+
+ /* Flow fields. */
+ backer->rt_support.odp.ct_state = false;
+ backer->rt_support.odp.ct_zone = false;
+ backer->rt_support.odp.ct_mark = false;
+ backer->rt_support.odp.ct_label = false;
+
+ backer->rt_support.odp.ct_state_nat = false;
+ backer->rt_support.odp.ct_orig_tuple = false;
+ backer->rt_support.odp.ct_orig_tuple6 = false;
+ } else {
+ /* Actions. */
+ backer->rt_support.odp.recirc = check_recirc(backer);
+ backer->rt_support.odp.max_vlan_headers = check_max_vlan_headers(backer);
+ backer->rt_support.odp.max_mpls_depth = check_max_mpls_depth(backer);
+ backer->rt_support.masked_set_action = check_masked_set_action(backer);
+ backer->rt_support.trunc = check_trunc_action(backer);
+ backer->rt_support.ufid = check_ufid(backer);
+ backer->rt_support.tnl_push_pop = dpif_supports_tnl_push_pop(backer->dpif);
+ backer->rt_support.clone = check_clone(backer);
+ backer->rt_support.sample_nesting = check_max_sample_nesting(backer);
+ backer->rt_support.ct_eventmask = check_ct_eventmask(backer);
+ backer->rt_support.ct_clear = check_ct_clear(backer);
+
+ /* Flow fields. */
+ backer->rt_support.odp.ct_state = check_ct_state(backer);
+ backer->rt_support.odp.ct_zone = check_ct_zone(backer);
+ backer->rt_support.odp.ct_mark = check_ct_mark(backer);
+ backer->rt_support.odp.ct_label = check_ct_label(backer);
+
+ backer->rt_support.odp.ct_state_nat = check_ct_state_nat(backer);
+ backer->rt_support.odp.ct_orig_tuple = check_ct_orig_tuple(backer);
+ backer->rt_support.odp.ct_orig_tuple6 = check_ct_orig_tuple6(backer);
+ }
}

static int
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index f44f950a4fce..ca6d73810420 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -20,6 +20,7 @@
#include <stdlib.h>

#include "async-append.h"
+#include "bpf.h"
#include "bfd.h"
#include "bitmap.h"
#include "cfm.h"
@@ -508,6 +509,25 @@ bridge_exit(bool delete_datapath)
ovsdb_idl_destroy(idl);
}

+static int
+init_ebpf(const struct ovsrec_open_vswitch *ovs_cfg OVS_UNUSED)
+{
+ static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+ static int error = 0;
+
+ if (ovsthread_once_start(&once)) {
+ char *bpf_elf = xasprintf("%s/bpf/datapath.o", ovs_pkgdatadir());
+
+ error = bpf_init();
+ if (!error) {
+ error = bpf_load(bpf_elf);
+ }
+ free(bpf_elf);
+ ovsthread_once_done(&once);
+ }
+ return error;
+}
+
/* Looks at the list of managers in 'ovs_cfg' and extracts their remote IP
* addresses and ports into '*managersp' and '*n_managersp'. The caller is
* responsible for freeing '*managersp' (with free()).
@@ -2979,6 +2999,7 @@ bridge_run(void)
if (cfg) {
netdev_set_flow_api_enabled(&cfg->other_config);
dpdk_init(&cfg->other_config);
+ init_ebpf(cfg);
}

/* Initialize the ofproto library. This only needs to run once, but
--
2.7.4