[ovs-dev] [RFC PATCHv2 08/13] vswitch/bridge.c: add bpf datapath initialization.

William Tu u9012063 at gmail.com
Sat Jul 14 11:39:00 UTC 2018


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 at ovn.org>
Signed-off-by: William Tu <u9012063 at gmail.com>
Signed-off-by: Yifeng Sun <pkusunyifeng at gmail.com>
Co-authored-by: William Tu <u9012063 at gmail.com>
Co-authored-by: Yifeng Sun <pkusunyifeng at gmail.com>
---
 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



More information about the dev mailing list