diff --git a/package/qca/nss/qca-nss-ecm/Makefile b/package/qca/nss/qca-nss-ecm/Makefile index 0ed611df0..06ce3ffc4 100644 --- a/package/qca/nss/qca-nss-ecm/Makefile +++ b/package/qca/nss/qca-nss-ecm/Makefile @@ -218,10 +218,6 @@ 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) diff --git a/package/qca/nss/qca-nss-ecm/patches/204-add-macvlan-acceleration-support.patch b/package/qca/nss/qca-nss-ecm/patches/204-add-macvlan-acceleration-support.patch deleted file mode 100644 index 1c0879dd6..000000000 --- a/package/qca/nss/qca-nss-ecm/patches/204-add-macvlan-acceleration-support.patch +++ /dev/null @@ -1,628 +0,0 @@ ---- 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 - #endif -+#ifdef ECM_INTERFACE_MACVLAN_ENABLE -+#include -+#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);