[ovs-dev] [PATCH ovn 1/6] controller: Split mac learning code to a separate file.
numans at ovn.org
numans at ovn.org
Fri Feb 5 06:59:12 UTC 2021
From: Numan Siddique <numans at ovn.org>
This patch moves the 'struct put_mac_binding' from controller/pinctrl.c
to controller/mac-learn.c as a 'struct mac_binding' and adds the
relevant functions to access it.
Signed-off-by: Numan Siddique <numans at ovn.org>
---
controller/automake.mk | 5 +-
controller/mac-learn.c | 101 ++++++++++++++++++++++++++++++++++++++++
controller/mac-learn.h | 46 +++++++++++++++++++
controller/pinctrl.c | 102 ++++++++++++-----------------------------
4 files changed, 181 insertions(+), 73 deletions(-)
create mode 100644 controller/mac-learn.c
create mode 100644 controller/mac-learn.h
diff --git a/controller/automake.mk b/controller/automake.mk
index 480578eda3..9b8debd2ff 100644
--- a/controller/automake.mk
+++ b/controller/automake.mk
@@ -27,7 +27,10 @@ controller_ovn_controller_SOURCES = \
controller/ovn-controller.c \
controller/ovn-controller.h \
controller/physical.c \
- controller/physical.h
+ controller/physical.h \
+ controller/mac-learn.c \
+ controller/mac-learn.h
+
controller_ovn_controller_LDADD = lib/libovn.la $(OVS_LIBDIR)/libopenvswitch.la
man_MANS += controller/ovn-controller.8
EXTRA_DIST += controller/ovn-controller.8.xml
diff --git a/controller/mac-learn.c b/controller/mac-learn.c
new file mode 100644
index 0000000000..36a6d6e589
--- /dev/null
+++ b/controller/mac-learn.c
@@ -0,0 +1,101 @@
+/* Copyright (c) 2020, Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include "mac-learn.h"
+
+/* OpenvSwitch lib includes. */
+#include "openvswitch/vlog.h"
+#include "lib/smap.h"
+
+VLOG_DEFINE_THIS_MODULE(mac_learn);
+
+#define MAX_MAC_BINDINGS 1000
+
+static size_t mac_binding_hash(uint32_t dp_key, uint32_t port_key,
+ struct in6_addr *);
+static struct mac_binding *mac_binding_find(struct hmap *mac_bindings,
+ uint32_t dp_key,
+ uint32_t port_key,
+ struct in6_addr *ip, size_t hash);
+
+void
+ovn_mac_bindings_init(struct hmap *mac_bindings)
+{
+ hmap_init(mac_bindings);
+}
+
+void
+ovn_mac_bindings_flush(struct hmap *mac_bindings)
+{
+ struct mac_binding *mb;
+ HMAP_FOR_EACH_POP (mb, hmap_node, mac_bindings) {
+ free(mb);
+ }
+}
+
+void
+ovn_mac_bindings_destroy(struct hmap *mac_bindings)
+{
+ ovn_mac_bindings_flush(mac_bindings);
+ hmap_destroy(mac_bindings);
+}
+
+struct mac_binding *
+ovn_mac_binding_add(struct hmap *mac_bindings, uint32_t dp_key,
+ uint32_t port_key, struct in6_addr *ip,
+ struct eth_addr mac)
+{
+ uint32_t hash = mac_binding_hash(dp_key, port_key, ip);
+
+ struct mac_binding *mb =
+ mac_binding_find(mac_bindings, dp_key, port_key, ip, hash);
+ if (!mb) {
+ if (hmap_count(mac_bindings) >= MAX_MAC_BINDINGS) {
+ return NULL;
+ }
+
+ mb = xmalloc(sizeof *mb);
+ mb->dp_key = dp_key;
+ mb->port_key = port_key;
+ mb->ip = *ip;
+ hmap_insert(mac_bindings, &mb->hmap_node, hash);
+ }
+ mb->mac = mac;
+
+ return mb;
+}
+
+static size_t
+mac_binding_hash(uint32_t dp_key, uint32_t port_key, struct in6_addr *ip)
+{
+ return hash_bytes(ip, sizeof *ip, hash_2words(dp_key, port_key));
+}
+
+static struct mac_binding *
+mac_binding_find(struct hmap *mac_bindings, uint32_t dp_key,
+ uint32_t port_key, struct in6_addr *ip, size_t hash)
+{
+ struct mac_binding *mb;
+ HMAP_FOR_EACH_WITH_HASH (mb, hmap_node, hash, mac_bindings) {
+ if (mb->dp_key == dp_key && mb->port_key == port_key &&
+ IN6_ARE_ADDR_EQUAL(&mb->ip, ip)) {
+ return mb;
+ }
+ }
+
+ return NULL;
+}
diff --git a/controller/mac-learn.h b/controller/mac-learn.h
new file mode 100644
index 0000000000..3a8520c360
--- /dev/null
+++ b/controller/mac-learn.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVN_MAC_LEARN_H
+#define OVN_MAC_LEARN_H 1
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include "openvswitch/hmap.h"
+
+struct mac_binding {
+ struct hmap_node hmap_node; /* In a hmap. */
+
+ /* Key. */
+ uint32_t dp_key;
+ uint32_t port_key; /* Port from where this mac_binding is learnt. */
+ struct in6_addr ip;
+
+ /* Value. */
+ struct eth_addr mac;
+};
+
+void ovn_mac_bindings_init(struct hmap *mac_bindings);
+void ovn_mac_bindings_flush(struct hmap *mac_bindings);
+void ovn_mac_bindings_destroy(struct hmap *mac_bindings);
+
+struct mac_binding *ovn_mac_binding_add(struct hmap *mac_bindings,
+ uint32_t dp_key, uint32_t port_key,
+ struct in6_addr *ip,
+ struct eth_addr mac);
+
+
+#endif /* OVN_MAC_LEARN_H */
\ No newline at end of file
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index dcf6b4af5c..723d2a6522 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -26,6 +26,7 @@
#include "flow.h"
#include "ha-chassis.h"
#include "lport.h"
+#include "mac-learn.h"
#include "nx-match.h"
#include "latch.h"
#include "lib/packets.h"
@@ -193,7 +194,6 @@ static void run_put_mac_bindings(
struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip)
OVS_REQUIRES(pinctrl_mutex);
static void wait_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn);
-static void flush_put_mac_bindings(void);
static void send_mac_binding_buffered_pkts(struct rconn *swconn)
OVS_REQUIRES(pinctrl_mutex);
@@ -3893,47 +3893,20 @@ pinctrl_destroy(void)
* available. */
/* Buffered "put_mac_binding" operation. */
-struct put_mac_binding {
- struct hmap_node hmap_node; /* In 'put_mac_bindings'. */
- /* Key. */
- uint32_t dp_key;
- uint32_t port_key;
- struct in6_addr ip_key;
-
- /* Value. */
- struct eth_addr mac;
-};
-
-/* Contains "struct put_mac_binding"s. */
+/* Contains "struct mac_binding"s. */
static struct hmap put_mac_bindings;
static void
init_put_mac_bindings(void)
{
- hmap_init(&put_mac_bindings);
+ ovn_mac_bindings_init(&put_mac_bindings);
}
static void
destroy_put_mac_bindings(void)
{
- flush_put_mac_bindings();
- hmap_destroy(&put_mac_bindings);
-}
-
-static struct put_mac_binding *
-pinctrl_find_put_mac_binding(uint32_t dp_key, uint32_t port_key,
- const struct in6_addr *ip_key, uint32_t hash)
-{
- struct put_mac_binding *pa;
- HMAP_FOR_EACH_WITH_HASH (pa, hmap_node, hash, &put_mac_bindings) {
- if (pa->dp_key == dp_key
- && pa->port_key == port_key
- && IN6_ARE_ADDR_EQUAL(&pa->ip_key, ip_key)) {
- return pa;
- }
- }
- return NULL;
+ ovn_mac_bindings_destroy(&put_mac_bindings);
}
/* Called with in the pinctrl_handler thread context. */
@@ -3953,23 +3926,16 @@ pinctrl_handle_put_mac_binding(const struct flow *md,
ovs_be128 ip6 = hton128(flow_get_xxreg(md, 0));
memcpy(&ip_key, &ip6, sizeof ip_key);
}
- uint32_t hash = hash_bytes(&ip_key, sizeof ip_key,
- hash_2words(dp_key, port_key));
- struct put_mac_binding *pmb
- = pinctrl_find_put_mac_binding(dp_key, port_key, &ip_key, hash);
- if (!pmb) {
+
+ struct mac_binding *mb = ovn_mac_binding_add(&put_mac_bindings, dp_key,
+ port_key, &ip_key,
+ headers->dl_src);
+ if (!mb) {
if (hmap_count(&put_mac_bindings) >= 1000) {
COVERAGE_INC(pinctrl_drop_put_mac_binding);
return;
}
-
- pmb = xmalloc(sizeof *pmb);
- hmap_insert(&put_mac_bindings, &pmb->hmap_node, hash);
- pmb->dp_key = dp_key;
- pmb->port_key = port_key;
- pmb->ip_key = ip_key;
}
- pmb->mac = headers->dl_src;
/* We can send the buffered packet once the main ovn-controller
* thread calls pinctrl_run() and it writes the mac_bindings stored
@@ -4012,12 +3978,12 @@ mac_binding_lookup(struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
/* Update or add an IP-MAC binding for 'logical_port'.
* Caller should make sure that 'ovnsb_idl_txn' is valid. */
static void
-mac_binding_add(struct ovsdb_idl_txn *ovnsb_idl_txn,
- struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
- const char *logical_port,
- const struct sbrec_datapath_binding *dp,
- struct eth_addr ea, const char *ip,
- bool update_only)
+mac_binding_add_to_sb(struct ovsdb_idl_txn *ovnsb_idl_txn,
+ struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
+ const char *logical_port,
+ const struct sbrec_datapath_binding *dp,
+ struct eth_addr ea, const char *ip,
+ bool update_only)
{
/* Convert ethernet argument to string form for database. */
char mac_string[ETH_ADDR_STRLEN + 1];
@@ -4073,9 +4039,9 @@ send_garp_locally(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ds ip_s = DS_EMPTY_INITIALIZER;
ip_format_masked(ip, OVS_BE32_MAX, &ip_s);
- mac_binding_add(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
- remote->logical_port, remote->datapath,
- ea, ds_cstr(&ip_s), update_only);
+ mac_binding_add_to_sb(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
+ remote->logical_port, remote->datapath,
+ ea, ds_cstr(&ip_s), update_only);
ds_destroy(&ip_s);
}
}
@@ -4085,30 +4051,30 @@ run_put_mac_binding(struct ovsdb_idl_txn *ovnsb_idl_txn,
struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
struct ovsdb_idl_index *sbrec_port_binding_by_key,
struct ovsdb_idl_index *sbrec_mac_binding_by_lport_ip,
- const struct put_mac_binding *pmb)
+ const struct mac_binding *mb)
{
/* Convert logical datapath and logical port key into lport. */
const struct sbrec_port_binding *pb = lport_lookup_by_key(
sbrec_datapath_binding_by_key, sbrec_port_binding_by_key,
- pmb->dp_key, pmb->port_key);
+ mb->dp_key, mb->port_key);
if (!pb) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
VLOG_WARN_RL(&rl, "unknown logical port with datapath %"PRIu32" "
- "and port %"PRIu32, pmb->dp_key, pmb->port_key);
+ "and port %"PRIu32, mb->dp_key, mb->port_key);
return;
}
/* Convert ethernet argument to string form for database. */
char mac_string[ETH_ADDR_STRLEN + 1];
snprintf(mac_string, sizeof mac_string,
- ETH_ADDR_FMT, ETH_ADDR_ARGS(pmb->mac));
+ ETH_ADDR_FMT, ETH_ADDR_ARGS(mb->mac));
struct ds ip_s = DS_EMPTY_INITIALIZER;
- ipv6_format_mapped(&pmb->ip_key, &ip_s);
- mac_binding_add(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
- pb->logical_port, pb->datapath, pmb->mac, ds_cstr(&ip_s),
- false);
+ ipv6_format_mapped(&mb->ip, &ip_s);
+ mac_binding_add_to_sb(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip,
+ pb->logical_port, pb->datapath, mb->mac,
+ ds_cstr(&ip_s), false);
ds_destroy(&ip_s);
}
@@ -4125,14 +4091,14 @@ run_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn,
return;
}
- const struct put_mac_binding *pmb;
- HMAP_FOR_EACH (pmb, hmap_node, &put_mac_bindings) {
+ const struct mac_binding *mb;
+ HMAP_FOR_EACH (mb, hmap_node, &put_mac_bindings) {
run_put_mac_binding(ovnsb_idl_txn, sbrec_datapath_binding_by_key,
sbrec_port_binding_by_key,
sbrec_mac_binding_by_lport_ip,
- pmb);
+ mb);
}
- flush_put_mac_bindings();
+ ovn_mac_bindings_flush(&put_mac_bindings);
}
static void
@@ -4188,14 +4154,6 @@ wait_put_mac_bindings(struct ovsdb_idl_txn *ovnsb_idl_txn)
}
}
-static void
-flush_put_mac_bindings(void)
-{
- struct put_mac_binding *pmb;
- HMAP_FOR_EACH_POP (pmb, hmap_node, &put_mac_bindings) {
- free(pmb);
- }
-}
/*
* Send gratuitous/reverse ARP for vif on localnet.
--
2.29.2
More information about the dev
mailing list