mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
629 lines
21 KiB
Diff
629 lines
21 KiB
Diff
--- 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);
|