mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 14:23:38 +00:00
qca-nss-ecm: add support for macvlan interface acceleration
This commit is contained in:
parent
7da518b715
commit
29c93682aa
@ -218,6 +218,10 @@ ECM_MAKE_OPTS+=ECM_INTERFACE_OVS_BRIDGE_ENABLE=y \
|
||||
EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-ovsmgr
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_PACKAGE_kmod-macvlan),)
|
||||
ECM_MAKE_OPTS+=ECM_INTERFACE_MACVLAN_ENABLE=y
|
||||
endif
|
||||
|
||||
# Keeping default as ipq806x for branches that does not have subtarget framework
|
||||
ifeq ($(CONFIG_TARGET_ipq),y)
|
||||
subtarget:=$(SUBTARGET)
|
||||
|
@ -0,0 +1,628 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -196,6 +196,11 @@ ECM_INTERFACE_VLAN_ENABLE=y
|
||||
ccflags-$(ECM_INTERFACE_VLAN_ENABLE) += -DECM_INTERFACE_VLAN_ENABLE
|
||||
|
||||
# #############################################################################
|
||||
+# Define ECM_INTERFACE_MACVLAN_ENABLE=y in order to enable support for MACVLAN
|
||||
+# #############################################################################
|
||||
+ccflags-$(ECM_INTERFACE_MACVLAN_ENABLE) += -DECM_INTERFACE_MACVLAN_ENABLE
|
||||
+
|
||||
+# #############################################################################
|
||||
# Define ECM_INTERFACE_IPSEC_ENABLE=y in order to enable support for IPSEC
|
||||
# #############################################################################
|
||||
ccflags-$(ECM_INTERFACE_IPSEC_ENABLE) += -DECM_INTERFACE_IPSEC_ENABLE
|
||||
--- a/ecm_interface.c
|
||||
+++ b/ecm_interface.c
|
||||
@@ -94,6 +94,9 @@
|
||||
#ifdef ECM_INTERFACE_OVS_BRIDGE_ENABLE
|
||||
#include <ovsmgr.h>
|
||||
#endif
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+#include <linux/if_macvlan.h>
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Debug output levels
|
||||
@@ -1498,6 +1501,58 @@ static struct ecm_db_iface_instance *ecm
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+/*
|
||||
+ * ecm_interface_macvlan_interface_establish()
|
||||
+ * Returns a reference to a iface of the MACVLAN type, possibly creating one if necessary.
|
||||
+ * Returns NULL on failure or a reference to interface.
|
||||
+ */
|
||||
+static struct ecm_db_iface_instance *ecm_interface_macvlan_interface_establish(struct ecm_db_interface_info_macvlan *type_info,
|
||||
+ char *dev_name, int32_t dev_interface_num, int32_t ae_interface_num, int32_t mtu)
|
||||
+{
|
||||
+ struct ecm_db_iface_instance *nii;
|
||||
+ struct ecm_db_iface_instance *ii;
|
||||
+
|
||||
+ DEBUG_INFO("Establish MACVLAN iface: %s with address: %pM, MTU: %d, if num: %d, accel engine if id: %d\n",
|
||||
+ dev_name, type_info->address, mtu, dev_interface_num, ae_interface_num);
|
||||
+
|
||||
+ /*
|
||||
+ * Locate the iface
|
||||
+ */
|
||||
+ ii = ecm_db_iface_find_and_ref_macvlan(type_info->address);
|
||||
+ if (ii) {
|
||||
+ DEBUG_TRACE("%px: iface established\n", ii);
|
||||
+ return ii;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * No iface - create one
|
||||
+ */
|
||||
+ nii = ecm_db_iface_alloc();
|
||||
+ if (!nii) {
|
||||
+ DEBUG_WARN("Failed to establish iface\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Add iface into the database, atomically to avoid races creating the same thing
|
||||
+ */
|
||||
+ spin_lock_bh(&ecm_interface_lock);
|
||||
+ ii = ecm_db_iface_find_and_ref_macvlan(type_info->address);
|
||||
+ if (ii) {
|
||||
+ spin_unlock_bh(&ecm_interface_lock);
|
||||
+ ecm_db_iface_deref(nii);
|
||||
+ return ii;
|
||||
+ }
|
||||
+ ecm_db_iface_add_macvlan(nii, type_info->address, dev_name,
|
||||
+ mtu, dev_interface_num, ae_interface_num, NULL, nii);
|
||||
+ spin_unlock_bh(&ecm_interface_lock);
|
||||
+
|
||||
+ DEBUG_TRACE("%px: MACVLAN iface established\n", nii);
|
||||
+ return nii;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#ifdef ECM_INTERFACE_OVS_BRIDGE_ENABLE
|
||||
/*
|
||||
* ecm_interface_multicast_ovs_to_interface_get_and_ref()
|
||||
@@ -2634,6 +2689,28 @@ static struct net_device *ecm_interface_
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+/*
|
||||
+ * ecm_interface_macvlan_mode_is_valid()
|
||||
+ * Check if the macvlan interface allowed for acceleration.
|
||||
+ */
|
||||
+static bool ecm_interface_macvlan_mode_is_valid(struct net_device *dev)
|
||||
+{
|
||||
+ enum macvlan_mode mode = macvlan_get_mode(dev);
|
||||
+
|
||||
+ /*
|
||||
+ * Allow acceleration for only "Private" mode.
|
||||
+ */
|
||||
+ if (mode == MACVLAN_MODE_PRIVATE) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_WARN("%px: MACVLAN dev: %s, MACVLAN mode: %d is not supported for acceleration\n", dev,
|
||||
+ dev->name, mode);
|
||||
+ return false;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* ecm_interface_establish_and_ref()
|
||||
* Establish an interface instance for the given interface detail.
|
||||
@@ -2653,6 +2730,9 @@ struct ecm_db_iface_instance *ecm_interf
|
||||
#ifdef ECM_INTERFACE_VLAN_ENABLE
|
||||
struct ecm_db_interface_info_vlan vlan; /* type == ECM_DB_IFACE_TYPE_VLAN */
|
||||
#endif
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ struct ecm_db_interface_info_macvlan macvlan; /* type == ECM_DB_IFACE_TYPE_MACVLAN */
|
||||
+#endif
|
||||
#ifdef ECM_INTERFACE_BOND_ENABLE
|
||||
struct ecm_db_interface_info_lag lag; /* type == ECM_DB_IFACE_TYPE_LAG */
|
||||
#endif
|
||||
@@ -2780,6 +2860,28 @@ struct ecm_db_iface_instance *ecm_interf
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ /*
|
||||
+ * MACVLAN?
|
||||
+ */
|
||||
+ if (netif_is_macvlan(dev)) {
|
||||
+ if (ecm_interface_macvlan_mode_is_valid(dev)) {
|
||||
+ ether_addr_copy(type_info.macvlan.address, dev->dev_addr);
|
||||
+ DEBUG_TRACE("%px: Net device: %px is MACVLAN, mac: %pM\n",
|
||||
+ feci, dev, type_info.macvlan.address);
|
||||
+
|
||||
+ /*
|
||||
+ * Establish this type of interface
|
||||
+ */
|
||||
+ ii = ecm_interface_macvlan_interface_establish(&type_info.macvlan, dev_name, dev_interface_num, ae_interface_num, dev_mtu);
|
||||
+ goto identifier_update;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_WARN("%px: Net device %px MACVLAN mode is not supported.\n", feci, dev);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
#ifdef ECM_INTERFACE_VXLAN_ENABLE
|
||||
/*
|
||||
* VxLAN?
|
||||
@@ -3606,6 +3708,21 @@ static uint32_t ecm_interface_multicast_
|
||||
break;
|
||||
}
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ /*
|
||||
+ * MAC-VLAN?
|
||||
+ */
|
||||
+ if (netif_is_macvlan(dest_dev)) {
|
||||
+ if (ecm_interface_macvlan_mode_is_valid(dest_dev)) {
|
||||
+ next_dev = macvlan_dev_real_dev(dest_dev);
|
||||
+ dev_hold(next_dev);
|
||||
+ DEBUG_TRACE("%px: Net device: %px is MAC-VLAN, slave dev: %px (%s)\n",
|
||||
+ feci, dest_dev, next_dev, next_dev->name);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
#ifdef ECM_INTERFACE_BOND_ENABLE
|
||||
/*
|
||||
* LAG?
|
||||
@@ -4746,6 +4863,35 @@ int32_t ecm_interface_heirarchy_construc
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ /*
|
||||
+ * MAC-VLAN?
|
||||
+ */
|
||||
+ if (netif_is_macvlan(dest_dev)) {
|
||||
+ if (ecm_interface_macvlan_mode_is_valid(dest_dev)) {
|
||||
+ next_dev = macvlan_dev_real_dev(dest_dev);
|
||||
+ dev_hold(next_dev);
|
||||
+ DEBUG_TRACE("%px: Net device: %px is MAC-VLAN, slave dev: %px (%s)\n",
|
||||
+ feci, dest_dev, next_dev, next_dev->name);
|
||||
+
|
||||
+ /*
|
||||
+ * We need to take the master_dev's MAC address during
|
||||
+ * NSS rule push. During VLAN/MACVLAN the master_dev for the
|
||||
+ * physical interface will be set to NULL but still we need the
|
||||
+ * VLAN/MACVLAN dev's MAC address while pushing the rule. We identify
|
||||
+ * the same using top_dev variable.
|
||||
+ */
|
||||
+ if (current_interface_index == (ECM_DB_IFACE_HEIRARCHY_MAX - 1)) {
|
||||
+ top_dev = dest_dev;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_WARN("%px: Net device %px MACVLAN mode is not supported.\n", feci, dest_dev);
|
||||
+ goto done;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* BRIDGE?
|
||||
*/
|
||||
@@ -5595,6 +5741,21 @@ int32_t ecm_interface_multicast_from_hei
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ /*
|
||||
+ * MAC-VLAN?
|
||||
+ */
|
||||
+ if (netif_is_macvlan(dest_dev)) {
|
||||
+ if (ecm_interface_macvlan_mode_is_valid(dest_dev)) {
|
||||
+ next_dev = macvlan_dev_real_dev(dest_dev);
|
||||
+ dev_hold(next_dev);
|
||||
+ DEBUG_TRACE("%px: Net device: %px is MAC-VLAN, slave dev: %px (%s)\n",
|
||||
+ feci, dest_dev, next_dev, next_dev->name);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* BRIDGE?
|
||||
*/
|
||||
@@ -6041,10 +6202,13 @@ static void ecm_interface_ovpn_stats_upd
|
||||
* Given an interface list, walk the interfaces and update the stats for certain types.
|
||||
*/
|
||||
static void ecm_interface_list_stats_update(int iface_list_first, struct ecm_db_iface_instance *iface_list[],
|
||||
- uint8_t *mac_addr, bool is_mcast_flow, uint32_t tx_packets, uint32_t tx_bytes, uint32_t rx_packets,
|
||||
+ uint8_t *mac_addr, bool is_mcast_to_if, uint32_t tx_packets, uint32_t tx_bytes, uint32_t rx_packets,
|
||||
uint32_t rx_bytes, bool is_ported, struct ecm_db_connection_instance *ci)
|
||||
{
|
||||
int list_index;
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ bool update_mcast_rx_stats = false;
|
||||
+#endif
|
||||
|
||||
for (list_index = iface_list_first; (list_index < ECM_DB_IFACE_HEIRARCHY_MAX); list_index++) {
|
||||
struct ecm_db_iface_instance *ii;
|
||||
@@ -6067,7 +6231,7 @@ static void ecm_interface_list_stats_upd
|
||||
}
|
||||
DEBUG_TRACE("found dev: %p (%s)\n", dev, dev->name);
|
||||
|
||||
- if (likely(!is_mcast_flow)) {
|
||||
+ if (likely(!is_mcast_to_if)) {
|
||||
/*
|
||||
* Refresh the bridge forward table entry if the port is a bridge port.
|
||||
* Refresh if the ci is a 3-tuple PPPoE bridge flow.
|
||||
@@ -6126,6 +6290,24 @@ static void ecm_interface_list_stats_upd
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ case ECM_DB_IFACE_TYPE_MACVLAN:
|
||||
+ DEBUG_INFO("MACVLAN\n");
|
||||
+ stats.rx_packets = rx_packets;
|
||||
+ stats.rx_bytes = rx_bytes;
|
||||
+ stats.tx_packets = tx_packets;
|
||||
+ stats.tx_bytes = tx_bytes;
|
||||
+#ifdef ECM_MULTICAST_ENABLE
|
||||
+ /*
|
||||
+ * Update multicast rx statistics only for
|
||||
+ * 'from' interface.
|
||||
+ */
|
||||
+ update_mcast_rx_stats = (!is_mcast_to_if &&
|
||||
+ ecm_db_multicast_connection_to_interfaces_set_check(ci));
|
||||
+#endif
|
||||
+ macvlan_offload_stats_update(dev, &stats, update_mcast_rx_stats);
|
||||
+ break;
|
||||
+#endif
|
||||
default:
|
||||
/*
|
||||
* TODO: Extend it accordingly
|
||||
@@ -6226,7 +6408,7 @@ void ecm_interface_multicast_stats_updat
|
||||
DEBUG_INFO("%p: Update from interface stats\n", ci);
|
||||
from_ifaces_first = ecm_db_connection_interfaces_get_and_ref(ci, from_ifaces, ECM_DB_OBJ_DIR_FROM);
|
||||
ecm_db_connection_node_address_get(ci, ECM_DB_OBJ_DIR_FROM, mac_addr);
|
||||
- ecm_interface_list_stats_update(from_ifaces_first, from_ifaces, mac_addr, false, from_tx_packets, from_tx_bytes, from_rx_packets, from_rx_bytes, is_ported, ci);
|
||||
+ ecm_interface_list_stats_update(from_ifaces_first, from_ifaces, mac_addr, false, 0, 0, from_rx_packets, from_rx_bytes, is_ported, ci);
|
||||
ecm_db_connection_interfaces_deref(from_ifaces, from_ifaces_first);
|
||||
|
||||
/*
|
||||
@@ -6250,7 +6432,7 @@ void ecm_interface_multicast_stats_updat
|
||||
if (to_ifaces_first[if_index] < ECM_DB_IFACE_HEIRARCHY_MAX) {
|
||||
ii_temp = ecm_db_multicast_if_heirarchy_get(to_ifaces, if_index);
|
||||
ecm_db_multicast_copy_if_heirarchy(to_list_single, ii_temp);
|
||||
- ecm_interface_list_stats_update(to_ifaces_first[if_index], to_list_single, mac_addr, true, to_tx_packets, to_tx_bytes, to_rx_packets, to_rx_bytes, is_ported, ci);
|
||||
+ ecm_interface_list_stats_update(to_ifaces_first[if_index], to_list_single, mac_addr, true, from_tx_packets, from_tx_bytes, 0, 0, is_ported, ci);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/ecm_db/ecm_db_types.h
|
||||
+++ b/ecm_db/ecm_db_types.h
|
||||
@@ -275,6 +275,7 @@ enum ecm_db_iface_types {
|
||||
ECM_DB_IFACE_TYPE_OVPN, /* Interface is a OVPN interface */
|
||||
ECM_DB_IFACE_TYPE_VXLAN, /* Interface is a VxLAN interface */
|
||||
ECM_DB_IFACE_TYPE_OVS_BRIDGE, /* Interface is a OpenvSwitch bridge interface */
|
||||
+ ECM_DB_IFACE_TYPE_MACVLAN, /* Interface is a MACVLAN interface */
|
||||
ECM_DB_IFACE_TYPE_COUNT, /* Number of interface types */
|
||||
};
|
||||
typedef enum ecm_db_iface_types ecm_db_iface_type_t;
|
||||
@@ -301,6 +302,12 @@ struct ecm_db_interface_info_vlan { /*
|
||||
};
|
||||
#endif
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+struct ecm_db_interface_info_macvlan { /* type == ECM_DB_IFACE_TYPE_MACVLAN */
|
||||
+ uint8_t address[ETH_ALEN]; /* MAC Address of this Interface */
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
#ifdef ECM_INTERFACE_BOND_ENABLE
|
||||
struct ecm_db_interface_info_lag { /* type == ECM_DB_IFACE_TYPE_LAG */
|
||||
uint8_t address[ETH_ALEN]; /* MAC Address of this Interface */
|
||||
--- a/ecm_db/ecm_db_iface.h
|
||||
+++ b/ecm_db/ecm_db_iface.h
|
||||
@@ -94,6 +94,9 @@ struct ecm_db_iface_instance {
|
||||
#ifdef ECM_INTERFACE_VLAN_ENABLE
|
||||
struct ecm_db_interface_info_vlan vlan; /* type == ECM_DB_IFACE_TYPE_VLAN */
|
||||
#endif
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ struct ecm_db_interface_info_macvlan macvlan; /* type == ECM_DB_IFACE_TYPE_MACVLAN */
|
||||
+#endif
|
||||
#ifdef ECM_INTERFACE_BOND_ENABLE
|
||||
struct ecm_db_interface_info_lag lag; /* type == ECM_DB_IFACE_TYPE_LAG */
|
||||
#endif
|
||||
@@ -215,6 +218,10 @@ void ecm_db_iface_add_vlan(struct ecm_db
|
||||
#endif
|
||||
|
||||
struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_bridge(uint8_t *address);
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_macvlan(uint8_t *address);
|
||||
+void ecm_db_iface_macvlan_address_get(struct ecm_db_iface_instance *ii, uint8_t *address);
|
||||
+#endif
|
||||
#ifdef ECM_INTERFACE_OVS_BRIDGE_ENABLE
|
||||
struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_ovs_bridge(uint8_t *address);
|
||||
#endif
|
||||
@@ -338,6 +345,11 @@ void ecm_db_iface_add_bridge(struct ecm_
|
||||
uint8_t *address, char *name, int32_t mtu, int32_t interface_identifier,
|
||||
int32_t ae_interface_identifier, ecm_db_iface_final_callback_t final, void *arg);
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+void ecm_db_iface_add_macvlan(struct ecm_db_iface_instance *ii,
|
||||
+ uint8_t *address, char *name, int32_t mtu, int32_t interface_identifier,
|
||||
+ int32_t ae_interface_identifier, ecm_db_iface_final_callback_t final, void *arg);
|
||||
+#endif
|
||||
#ifdef ECM_INTERFACE_OVS_BRIDGE_ENABLE
|
||||
void ecm_db_iface_add_ovs_bridge(struct ecm_db_iface_instance *ii,
|
||||
uint8_t *address, char *name, int32_t mtu, int32_t interface_identifier,
|
||||
--- a/ecm_db/ecm_db_iface.c
|
||||
+++ b/ecm_db/ecm_db_iface.c
|
||||
@@ -114,7 +114,8 @@ static char *ecm_db_interface_type_names
|
||||
"RAWIP",
|
||||
"OVPN",
|
||||
"VxLAN",
|
||||
- "OVS_BRIDGE"
|
||||
+ "OVS_BRIDGE",
|
||||
+ "MACVLAN"
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -381,6 +382,39 @@ static int ecm_db_iface_bridge_state_get
|
||||
return ecm_state_prefix_remove(sfi);
|
||||
}
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+/*
|
||||
+ * ecm_db_iface_macvlan_state_get()
|
||||
+ * Return interface type specific state
|
||||
+ */
|
||||
+static int ecm_db_iface_macvlan_state_get(struct ecm_db_iface_instance *ii, struct ecm_state_file_instance *sfi)
|
||||
+{
|
||||
+ int result;
|
||||
+ uint8_t address[ETH_ALEN];
|
||||
+
|
||||
+ DEBUG_CHECK_MAGIC(ii, ECM_DB_IFACE_INSTANCE_MAGIC, "%px: magic failed\n", ii);
|
||||
+ spin_lock_bh(&ecm_db_lock);
|
||||
+ memcpy(address, ii->type_info.macvlan.address, ETH_ALEN);
|
||||
+ spin_unlock_bh(&ecm_db_lock);
|
||||
+
|
||||
+ if ((result = ecm_state_prefix_add(sfi, "macvlan"))) {
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ if ((result = ecm_db_iface_state_get_base(ii, sfi))) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if ((result = ecm_state_write(sfi, "address", "%pM", address))) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ ecm_state_prefix_remove(sfi);
|
||||
+ return result;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#ifdef ECM_INTERFACE_OVS_BRIDGE_ENABLE
|
||||
/*
|
||||
* ecm_db_iface_ovs_bridge_state_get()
|
||||
@@ -475,7 +509,7 @@ static int ecm_db_iface_pppoe_state_get(
|
||||
return result;
|
||||
}
|
||||
|
||||
- if ((result = ecm_state_write(sfi, "remote_max", "%pM", remote_mac))) {
|
||||
+ if ((result = ecm_state_write(sfi, "remote_mac", "%pM", remote_mac))) {
|
||||
return result;
|
||||
}
|
||||
if ((result = ecm_state_write(sfi, "session_id", "%u", pppoe_session_id))) {
|
||||
@@ -1645,6 +1679,58 @@ struct ecm_db_iface_instance *ecm_db_ifa
|
||||
EXPORT_SYMBOL(ecm_db_iface_find_and_ref_vlan);
|
||||
#endif
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+/*
|
||||
+ * ecm_db_iface_find_and_ref_macvlan()
|
||||
+ * Lookup and return a iface reference if any
|
||||
+ */
|
||||
+struct ecm_db_iface_instance *ecm_db_iface_find_and_ref_macvlan(uint8_t *address)
|
||||
+{
|
||||
+ ecm_db_iface_hash_t hash_index;
|
||||
+ struct ecm_db_iface_instance *ii;
|
||||
+
|
||||
+ DEBUG_TRACE("Lookup macvlan iface with addr %pM\n", address);
|
||||
+
|
||||
+ /*
|
||||
+ * Compute the hash chain index and prepare to walk the chain
|
||||
+ */
|
||||
+ hash_index = ecm_db_iface_generate_hash_index_ethernet(address);
|
||||
+
|
||||
+ /*
|
||||
+ * Iterate the chain looking for a host with matching details
|
||||
+ */
|
||||
+ spin_lock_bh(&ecm_db_lock);
|
||||
+ ii = ecm_db_iface_table[hash_index];
|
||||
+ while (ii) {
|
||||
+ if ((ii->type != ECM_DB_IFACE_TYPE_MACVLAN) || !ether_addr_equal(ii->type_info.macvlan.address, address)) {
|
||||
+ ii = ii->hash_next;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ _ecm_db_iface_ref(ii);
|
||||
+ spin_unlock_bh(&ecm_db_lock);
|
||||
+ DEBUG_TRACE("iface found %px\n", ii);
|
||||
+ return ii;
|
||||
+ }
|
||||
+ spin_unlock_bh(&ecm_db_lock);
|
||||
+ DEBUG_TRACE("Iface not found\n");
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * ecm_db_iface_macvlan_address_get()
|
||||
+ * Obtain the ethernet address for a macvlan interface
|
||||
+ */
|
||||
+void ecm_db_iface_macvlan_address_get(struct ecm_db_iface_instance *ii, uint8_t *address)
|
||||
+{
|
||||
+ spin_lock_bh(&ecm_db_lock);
|
||||
+ DEBUG_CHECK_MAGIC(ii, ECM_DB_IFACE_INSTANCE_MAGIC, "%px: magic failed", ii);
|
||||
+ DEBUG_ASSERT(ii->type == ECM_DB_IFACE_TYPE_MACVLAN, "%px: Bad type, expected macvlan, actual: %d\n", ii, ii->type);
|
||||
+ ether_addr_copy(address, ii->type_info.macvlan.address);
|
||||
+ spin_unlock_bh(&ecm_db_lock);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#ifdef ECM_INTERFACE_VXLAN_ENABLE
|
||||
/*
|
||||
* ecm_db_iface_find_and_ref_vxlan()
|
||||
@@ -2752,6 +2838,57 @@ void ecm_db_iface_add_ovs_bridge(struct
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+/*
|
||||
+ * ecm_db_iface_add_macvlan()
|
||||
+ * Add a iface instance into the database
|
||||
+ */
|
||||
+void ecm_db_iface_add_macvlan(struct ecm_db_iface_instance *ii, uint8_t *address, char *name, int32_t mtu,
|
||||
+ int32_t interface_identifier, int32_t ae_interface_identifier,
|
||||
+ ecm_db_iface_final_callback_t final, void *arg)
|
||||
+{
|
||||
+ ecm_db_iface_hash_t hash_index;
|
||||
+ struct ecm_db_interface_info_macvlan *type_info;
|
||||
+
|
||||
+ spin_lock_bh(&ecm_db_lock);
|
||||
+ DEBUG_CHECK_MAGIC(ii, ECM_DB_IFACE_INSTANCE_MAGIC, "%px: magic failed\n", ii);
|
||||
+ DEBUG_ASSERT(address, "%px: address null\n", ii);
|
||||
+#ifdef ECM_DB_XREF_ENABLE
|
||||
+ DEBUG_ASSERT((ii->nodes == NULL) && (ii->node_count == 0), "%px: nodes not null\n", ii);
|
||||
+#endif
|
||||
+ DEBUG_ASSERT(!(ii->flags & ECM_DB_IFACE_FLAGS_INSERTED), "%px: inserted\n", ii);
|
||||
+ DEBUG_ASSERT(name, "%px: no name given\n", ii);
|
||||
+ spin_unlock_bh(&ecm_db_lock);
|
||||
+
|
||||
+ /*
|
||||
+ * Record general info
|
||||
+ */
|
||||
+ ii->type = ECM_DB_IFACE_TYPE_MACVLAN;
|
||||
+#ifdef ECM_STATE_OUTPUT_ENABLE
|
||||
+ ii->state_get = ecm_db_iface_macvlan_state_get;
|
||||
+#endif
|
||||
+ ii->arg = arg;
|
||||
+ ii->final = final;
|
||||
+ strlcpy(ii->name, name, IFNAMSIZ);
|
||||
+ ii->mtu = mtu;
|
||||
+ ii->interface_identifier = interface_identifier;
|
||||
+ ii->ae_interface_identifier = ae_interface_identifier;
|
||||
+
|
||||
+ /*
|
||||
+ * Type specific info
|
||||
+ */
|
||||
+ type_info = &ii->type_info.macvlan;
|
||||
+ ether_addr_copy(type_info->address, address);
|
||||
+
|
||||
+ /*
|
||||
+ * Compute hash chain for insertion
|
||||
+ */
|
||||
+ hash_index = ecm_db_iface_generate_hash_index_ethernet(address);
|
||||
+
|
||||
+ ecm_db_iface_add_to_db(ii, hash_index);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#ifdef ECM_INTERFACE_VLAN_ENABLE
|
||||
/*
|
||||
* ecm_db_iface_add_vlan()
|
||||
--- a/frontends/nss/ecm_nss_ported_ipv4.c
|
||||
+++ b/frontends/nss/ecm_nss_ported_ipv4.c
|
||||
@@ -662,6 +662,21 @@ static void ecm_nss_ported_ipv4_connecti
|
||||
DEBUG_TRACE("%p: VLAN - unsupported\n", npci);
|
||||
#endif
|
||||
break;
|
||||
+ case ECM_DB_IFACE_TYPE_MACVLAN:
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ ecm_db_iface_macvlan_address_get(ii, from_nss_iface_address);
|
||||
+ if (is_valid_ether_addr(from_nss_iface_address)) {
|
||||
+ ether_addr_copy((uint8_t *)nircm->src_mac_rule.flow_src_mac, from_nss_iface_address);
|
||||
+ nircm->src_mac_rule.mac_valid_flags |= NSS_IPV4_SRC_MAC_FLOW_VALID;
|
||||
+ nircm->valid_flags |= NSS_IPV4_RULE_CREATE_SRC_MAC_VALID;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_TRACE("%px: Macvlan - mac: %pM\n", npci, from_nss_iface_address);
|
||||
+#else
|
||||
+ rule_invalid = true;
|
||||
+ DEBUG_TRACE("%px: MACVLAN - unsupported\n", npci);
|
||||
+#endif
|
||||
+ break;
|
||||
case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
|
||||
#ifdef ECM_INTERFACE_IPSEC_ENABLE
|
||||
DEBUG_TRACE("%p: IPSEC\n", npci);
|
||||
@@ -929,6 +944,21 @@ static void ecm_nss_ported_ipv4_connecti
|
||||
DEBUG_TRACE("%p: VLAN - unsupported\n", npci);
|
||||
#endif
|
||||
break;
|
||||
+ case ECM_DB_IFACE_TYPE_MACVLAN:
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ ecm_db_iface_macvlan_address_get(ii, to_nss_iface_address);
|
||||
+ if (is_valid_ether_addr(to_nss_iface_address)) {
|
||||
+ ether_addr_copy((uint8_t *)nircm->src_mac_rule.return_src_mac, to_nss_iface_address);
|
||||
+ nircm->src_mac_rule.mac_valid_flags |= NSS_IPV4_SRC_MAC_RETURN_VALID;
|
||||
+ nircm->valid_flags |= NSS_IPV4_RULE_CREATE_SRC_MAC_VALID;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_TRACE("%px: Macvlan - mac: %pM\n", npci, to_nss_iface_address);
|
||||
+#else
|
||||
+ rule_invalid = true;
|
||||
+ DEBUG_TRACE("%px: MACVLAN - unsupported\n", npci);
|
||||
+#endif
|
||||
+ break;
|
||||
case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
|
||||
#ifdef ECM_INTERFACE_IPSEC_ENABLE
|
||||
DEBUG_TRACE("%p: IPSEC\n", npci);
|
||||
--- a/frontends/nss/ecm_nss_ported_ipv6.c
|
||||
+++ b/frontends/nss/ecm_nss_ported_ipv6.c
|
||||
@@ -657,6 +657,21 @@ static void ecm_nss_ported_ipv6_connecti
|
||||
DEBUG_TRACE("%p: VLAN - unsupported\n", npci);
|
||||
#endif
|
||||
break;
|
||||
+ case ECM_DB_IFACE_TYPE_MACVLAN:
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ ecm_db_iface_macvlan_address_get(ii, from_nss_iface_address);
|
||||
+ if (is_valid_ether_addr(from_nss_iface_address)) {
|
||||
+ ether_addr_copy((uint8_t *)nircm->src_mac_rule.flow_src_mac, from_nss_iface_address);
|
||||
+ nircm->src_mac_rule.mac_valid_flags |= NSS_IPV6_SRC_MAC_FLOW_VALID;
|
||||
+ nircm->valid_flags |= NSS_IPV6_RULE_CREATE_SRC_MAC_VALID;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_TRACE("%px: Macvlan - mac: %pM\n", npci, from_nss_iface_address);
|
||||
+#else
|
||||
+ rule_invalid = true;
|
||||
+ DEBUG_TRACE("%px: MACVLAN - unsupported\n", npci);
|
||||
+#endif
|
||||
+ break;
|
||||
case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
|
||||
#ifdef ECM_INTERFACE_IPSEC_ENABLE
|
||||
DEBUG_TRACE("%p: IPSEC\n", npci);
|
||||
@@ -899,6 +914,21 @@ static void ecm_nss_ported_ipv6_connecti
|
||||
DEBUG_TRACE("%p: VLAN - unsupported\n", npci);
|
||||
#endif
|
||||
break;
|
||||
+ case ECM_DB_IFACE_TYPE_MACVLAN:
|
||||
+#ifdef ECM_INTERFACE_MACVLAN_ENABLE
|
||||
+ ecm_db_iface_macvlan_address_get(ii, to_nss_iface_address);
|
||||
+ if (is_valid_ether_addr(to_nss_iface_address)) {
|
||||
+ ether_addr_copy((uint8_t *)nircm->src_mac_rule.return_src_mac, to_nss_iface_address);
|
||||
+ nircm->src_mac_rule.mac_valid_flags |= NSS_IPV6_SRC_MAC_RETURN_VALID;
|
||||
+ nircm->valid_flags |= NSS_IPV6_RULE_CREATE_SRC_MAC_VALID;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_TRACE("%px: Macvlan - mac: %pM\n", npci, to_nss_iface_address);
|
||||
+#else
|
||||
+ rule_invalid = true;
|
||||
+ DEBUG_TRACE("%px: MACVLAN - unsupported\n", npci);
|
||||
+#endif
|
||||
+ break;
|
||||
case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
|
||||
#ifdef ECM_INTERFACE_IPSEC_ENABLE
|
||||
DEBUG_TRACE("%p: IPSEC\n", npci);
|
Loading…
Reference in New Issue
Block a user