[qca-nss-ecm] Kernel 3.14 porting work.
Makefile:
Add enable/disable flag for SIT interface.
ecm_classifier_default.c
ecm_conntrack_notifier.c
ecm_db.c
ecm_tracker.c
ecm_tracker_datagram.c
ecm_tracker_udp.c
Add linux version include file.
ecm_classifier.h
Enable/disable classifier types.
ecm_front_end_ipv4.c
Netfilete hook changes.
Enable/disable certain types of unsupported interfaces and classifiers.
Net device master changes.
Conntrack connection accounting changes.
Ethernet MAC compare API change.
ecm_front_end_ipv6.c
Ethernet MAC compare API change.
ecm_init.c
Enable/disable certain types of unsupported interfaces and classifiers.
ecm_interface.c
ecm_interface.h
Add new net device master get function to abstract kernel differences.
Neighbor lookup changes for IPv4.
Enable/disable certain types of unsupported interfaces.
ecm_types.h
Add a new MAC address comparison API to abstract kernel differences.
Change-Id: I4e2e859c65afa91029268c3c0f28761fbc878c68
Signed-off-by: Murat Sezgin <msezgin@codeaurora.org>
diff --git a/Makefile b/Makefile
index 73e6314..b2f2155 100755
--- a/Makefile
+++ b/Makefile
@@ -50,6 +50,15 @@
ccflags-$(ECM_INTERFACE_PPP_ENABLE) += -DECM_INTERFACE_PPP_ENABLE
# #############################################################################
+# Define ECM_INTERFACE_SIT_ENABLE=y in order
+# to enable support for SIT interface.
+# #############################################################################
+ifeq ("$(KERNELVERSION)","3.4.0")
+ECM_INTERFACE_SIT_ENABLE=y
+endif
+ccflags-$(ECM_INTERFACE_SIT_ENABLE) += -DECM_INTERFACE_SIT_ENABLE
+
+# #############################################################################
# Define ECM_INTERFACE_VLAN_ENABLE=y in order to enable support for VLAN
# #############################################################################
ifeq ("$(KERNELVERSION)","3.4.0")
diff --git a/ecm_classifier.h b/ecm_classifier.h
index bcc4f28..7d43b93 100644
--- a/ecm_classifier.h
+++ b/ecm_classifier.h
@@ -25,8 +25,12 @@
#ifdef ECM_CLASSIFIER_HYFI_ENABLE
ECM_CLASSIFIER_TYPE_HYFI, /* HyFi classifier */
#endif
+#ifdef ECM_CLASSIFIER_DSCP_ENABLE
ECM_CLASSIFIER_TYPE_DSCP, /* Provides DSCP and DSCP remarking support */
+#endif
+#ifdef ECM_CLASSIFIER_NL_ENABLE
ECM_CLASSIFIER_TYPE_NL, /* Provides netlink interface */
+#endif
ECM_CLASSIFIER_TYPES, /* MUST BE LAST */
};
typedef enum ecm_classifier_types ecm_classifier_type_t;
diff --git a/ecm_classifier_default.c b/ecm_classifier_default.c
index c75814c..d2aced7 100644
--- a/ecm_classifier_default.c
+++ b/ecm_classifier_default.c
@@ -14,6 +14,7 @@
**************************************************************************
*/
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
diff --git a/ecm_conntrack_notifier.c b/ecm_conntrack_notifier.c
index 2ba5be2..6d75833 100644
--- a/ecm_conntrack_notifier.c
+++ b/ecm_conntrack_notifier.c
@@ -19,6 +19,7 @@
* Conntrack notifier functionality.
*/
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
diff --git a/ecm_db.c b/ecm_db.c
index 9d3d387..2774f9b 100644
--- a/ecm_db.c
+++ b/ecm_db.c
@@ -14,6 +14,7 @@
**************************************************************************
*/
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
diff --git a/ecm_front_end_ipv4.c b/ecm_front_end_ipv4.c
index 8883277..a61d98f 100644
--- a/ecm_front_end_ipv4.c
+++ b/ecm_front_end_ipv4.c
@@ -14,6 +14,7 @@
**************************************************************************
*/
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
@@ -255,8 +256,6 @@
done = true;
break;
- case ECM_DB_IFACE_TYPE_ETHERNET:
- case ECM_DB_IFACE_TYPE_LAG:
case ECM_DB_IFACE_TYPE_VLAN:
#ifdef ECM_INTERFACE_VLAN_ENABLE
/*
@@ -266,6 +265,8 @@
DEBUG_TRACE("VLAN interface unsupported\n");
return NULL;
#endif
+ case ECM_DB_IFACE_TYPE_ETHERNET:
+ case ECM_DB_IFACE_TYPE_LAG:
case ECM_DB_IFACE_TYPE_BRIDGE:
case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
if (!ecm_interface_mac_addr_get(addr, node_addr, &on_link, gw_addr)) {
@@ -2370,7 +2371,7 @@
DEBUG_TRACE("%p: vlan tag: %x\n", fecui, vlan_value);
#else
rule_invalid = true;
- DEBUG_TRACE("%p: VLAN - unsupported\n", fecti);
+ DEBUG_TRACE("%p: VLAN - unsupported\n", fecui);
#endif
break;
case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
@@ -2532,7 +2533,7 @@
DEBUG_TRACE("%p: vlan tag: %x\n", fecui, vlan_value);
#else
rule_invalid = true;
- DEBUG_TRACE("%p: VLAN - unsupported\n", fecti);
+ DEBUG_TRACE("%p: VLAN - unsupported\n", fecui);
#endif
break;
case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
@@ -3312,6 +3313,7 @@
}
#ifdef CONFIG_IPV6_SIT_6RD
+#ifdef ECM_INTERFACE_SIT_ENABLE
/*
* ecm_front_end_ipv4_sit_set_peer()
* It will set the tunnel's peer when the tunnel is a remote any tunnel.
@@ -3383,6 +3385,7 @@
ecm_db_connection_interfaces_deref(from_ifaces, from_ifaces_first);
}
#endif
+#endif
/*
* ecm_front_end_ipv4_connection_non_ported_callback()
@@ -3843,7 +3846,7 @@
DEBUG_TRACE("%p: vlan tag: %x\n", fecnpi, vlan_value);
#else
rule_invalid = true;
- DEBUG_TRACE("%p: VLAN - unsupported\n", fecti);
+ DEBUG_TRACE("%p: VLAN - unsupported\n", fecnpi);
#endif
break;
case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
@@ -4005,7 +4008,7 @@
DEBUG_TRACE("%p: vlan tag: %x\n", fecnpi, vlan_value);
#else
rule_invalid = true;
- DEBUG_TRACE("%p: VLAN - unsupported\n", fecti);
+ DEBUG_TRACE("%p: VLAN - unsupported\n", fecnpi);
#endif
break;
case ECM_DB_IFACE_TYPE_IPSEC_TUNNEL:
@@ -4817,6 +4820,8 @@
return (struct ecm_classifier_instance *)cnli;
}
#endif
+
+#ifdef ECM_CLASSIFIER_DSCP_ENABLE
if (type == ECM_CLASSIFIER_TYPE_DSCP) {
struct ecm_classifier_dscp_instance *cdscpi;
cdscpi = ecm_classifier_dscp_instance_alloc(ci);
@@ -4828,6 +4833,7 @@
ecm_db_connection_classifier_assign(ci, (struct ecm_classifier_instance *)cdscpi);
return (struct ecm_classifier_instance *)cdscpi;
}
+#endif
#ifdef ECM_CLASSIFIER_HYFI_ENABLE
if (type == ECM_CLASSIFIER_TYPE_HYFI) {
@@ -6912,6 +6918,7 @@
DEBUG_TRACE("%p: skb priority: %u\n", ci, skb->priority);
#ifdef CONFIG_IPV6_SIT_6RD
+#ifdef ECM_INTERFACE_SIT_ENABLE
/*
* SIT tunnel acceleration needs create a rule to the nss firmware if the
* tunnel's dest ip address is empty,it will get dest ip and the embedded ipv6's dest ip
@@ -6927,6 +6934,8 @@
feci->deref(feci);
}
#endif
+#endif
+
/*
* Accelerate?
*/
@@ -7359,11 +7368,19 @@
* ecm_front_end_ipv4_post_routing_hook()
* Called for IP packets that are going out to interfaces after IP routing stage.
*/
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
static unsigned int ecm_front_end_ipv4_post_routing_hook(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in_unused,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
+#else
+static unsigned int ecm_front_end_ipv4_post_routing_hook(const struct nf_hook_ops *ops,
+ struct sk_buff *skb,
+ const struct net_device *in_unused,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+#endif
{
struct net_device *in;
bool can_accel = true;
@@ -7407,11 +7424,19 @@
* These may have come from another bridged interface or from a non-bridged interface.
* Conntrack information may be available or not if this skb is bridged.
*/
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
static unsigned int ecm_front_end_ipv4_bridge_post_routing_hook(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in_unused,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
+#else
+static unsigned int ecm_front_end_ipv4_bridge_post_routing_hook(const struct nf_hook_ops *ops,
+ struct sk_buff *skb,
+ const struct net_device *in_unused,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+#endif
{
struct ethhdr *skb_eth_hdr;
uint16_t eth_type;
@@ -7458,15 +7483,17 @@
* Process.
*
* Begin by identifying case 1.
- * NOTE: We are given 'out' (which we implicitly know is a bridge port) so out->master is the 'bridge'.
+ * NOTE: We are given 'out' (which we implicitly know is a bridge port) so out interface's master is the 'bridge'.
*/
- bridge = out->master;
+ bridge = ecm_interface_get_and_hold_dev_master((struct net_device *)out);
+ DEBUG_ASSERT(bridge, "Expected bridge\n");
in = dev_get_by_index(&init_net, skb->skb_iif);
if (!in) {
/*
* Case 1.
*/
DEBUG_TRACE("Local traffic: %p, ignoring traffic to bridge: %p (%s) \n", skb, bridge, bridge->name);
+ dev_put(bridge);
return NF_ACCEPT;
}
dev_put(in);
@@ -7477,22 +7504,25 @@
* Case 3:
* If the packet was not local (case 1) or routed (case 2) then we process.
*/
- in = br_port_dev_get(out->master, skb_eth_hdr->h_source);
+ in = br_port_dev_get(bridge, skb_eth_hdr->h_source);
if (!in) {
DEBUG_TRACE("skb: %p, no in device for bridge: %p (%s)\n", skb, bridge, bridge->name);
+ dev_put(bridge);
return NF_ACCEPT;
}
if (in == out) {
DEBUG_TRACE("skb: %p, bridge: %p (%s), port bounce on %p (%s)\n", skb, bridge, bridge->name, out, out->name);
dev_put(in);
+ dev_put(bridge);
return NF_ACCEPT;
}
- if (!compare_ether_addr(skb_eth_hdr->h_source, bridge->dev_addr)) {
+ if (!ecm_mac_addr_equal(skb_eth_hdr->h_source, bridge->dev_addr)) {
/*
* Case 2: Routed trafffic would be handled by the INET post routing.
*/
DEBUG_TRACE("skb: %p, Ignoring routed packet to bridge: %p (%s)\n", skb, bridge, bridge->name);
dev_put(in);
+ dev_put(bridge);
return NF_ACCEPT;
}
@@ -7501,6 +7531,7 @@
result = ecm_front_end_ipv4_ip_process((struct net_device *)out, in,
skb_eth_hdr->h_source, skb_eth_hdr->h_dest, can_accel, false, skb);
dev_put(in);
+ dev_put(bridge);
return result;
}
@@ -7750,7 +7781,11 @@
spin_unlock_bh(&ct->lock);
}
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
acct = nf_conn_acct_find(ct);
+#else
+ acct = nf_conn_acct_find(ct)->counter;
+#endif
if (acct) {
spin_lock_bh(&ct->lock);
atomic64_add(sync->flow_rx_packet_count, &acct[IP_CT_DIR_ORIGINAL].packets);
@@ -7913,7 +7948,7 @@
static void ecm_front_end_ipv4_conntrack_event_mark(struct nf_conn *ct)
{
struct ecm_db_connection_instance *ci;
- struct ecm_classifier_instance *cls;
+ struct ecm_classifier_instance *__attribute__((unused))cls;
DEBUG_INFO("Mark event for ct: %p\n", ct);
diff --git a/ecm_front_end_ipv6.c b/ecm_front_end_ipv6.c
index 487cf29..9b9c0dc 100644
--- a/ecm_front_end_ipv6.c
+++ b/ecm_front_end_ipv6.c
@@ -7204,7 +7204,7 @@
dev_put(in);
return NF_ACCEPT;
}
- if (!compare_ether_addr(skb_eth_hdr->h_source, bridge->dev_addr)) {
+ if (!ecm_mac_addr_equal(skb_eth_hdr->h_source, bridge->dev_addr)) {
/*
* Case 2: Routed trafffic would be handled by the INET post routing.
*/
diff --git a/ecm_init.c b/ecm_init.c
index bde0c4a..fd16445 100644
--- a/ecm_init.c
+++ b/ecm_init.c
@@ -48,9 +48,11 @@
extern void ecm_interface_stop(int);
extern void ecm_interface_exit(void);
+#ifdef ECM_INTERFACE_BOND_ENABLE
extern int ecm_bond_notifier_init(void);
extern void ecm_bond_notifier_stop(int);
extern void ecm_bond_notifier_exit(void);
+#endif
extern int ecm_front_end_ipv4_init(void);
extern void ecm_front_end_ipv4_stop(int);
@@ -66,8 +68,10 @@
extern void ecm_conntrack_notifier_stop(int);
extern void ecm_conntrack_notifier_exit(void);
+#ifdef ECM_CLASSIFIER_DSCP_ENABLE
extern int ecm_classifier_dscp_init(void);
extern void ecm_classifier_dscp_exit(void);
+#endif
/*
* ecm_init()
@@ -121,20 +125,24 @@
}
#endif
+#ifdef ECM_CLASSIFIER_DSCP_ENABLE
ret = ecm_classifier_dscp_init();
if (0 != ret) {
goto err_cls_dscp;
}
+#endif
ret = ecm_interface_init();
if (0 != ret) {
goto err_iface;
}
+#ifdef ECM_INTERFACE_BOND_ENABLE
ret = ecm_bond_notifier_init();
if (0 != ret) {
goto err_bond;
}
+#endif
ret = ecm_front_end_ipv4_init();
if (0 != ret) {
@@ -163,12 +171,16 @@
#endif
ecm_front_end_ipv4_exit();
err_fe_ipv4:
+#ifdef ECM_INTERFACE_BOND_ENABLE
ecm_bond_notifier_exit();
err_bond:
+#endif
ecm_interface_exit();
err_iface:
+#ifdef ECM_CLASSIFIER_DSCP_ENABLE
ecm_classifier_dscp_exit();
err_cls_dscp:
+#endif
#ifdef ECM_CLASSIFIER_HYFI_ENABLE
ecm_classifier_hyfi_rules_exit();
err_cls_hyfi:
@@ -211,8 +223,10 @@
#endif
printk(KERN_INFO "stop interface\n");
ecm_interface_stop(1);
+#ifdef ECM_INTERFACE_BOND_ENABLE
printk(KERN_INFO "stop bond notifier\n");
ecm_bond_notifier_stop(1);
+#endif
printk(KERN_INFO "defunct all db connections\n");
ecm_db_connection_defunct_all();
@@ -225,12 +239,16 @@
printk(KERN_INFO "exit front_end_ipv6\n");
ecm_front_end_ipv6_exit();
#endif
+#ifdef ECM_INTERFACE_BOND_ENABLE
printk(KERN_INFO "exit bond notifier\n");
ecm_bond_notifier_exit();
+#endif
printk(KERN_INFO "exit interface\n");
ecm_interface_exit();
+#ifdef ECM_CLASSIFIER_DSCP_ENABLE
printk(KERN_INFO "exit dscp classifier\n");
ecm_classifier_dscp_exit();
+#endif
#ifdef ECM_CLASSIFIER_HYFI_ENABLE
printk(KERN_INFO "exit hyfi classifier\n");
ecm_classifier_hyfi_rules_exit();
diff --git a/ecm_interface.c b/ecm_interface.c
index f85cffb..febf03e 100644
--- a/ecm_interface.c
+++ b/ecm_interface.c
@@ -14,6 +14,7 @@
**************************************************************************
*/
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
@@ -43,7 +44,9 @@
#include <linux/inetdevice.h>
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
#include <net/ipip.h>
+#endif
#include <net/ip6_tunnel.h>
#include <net/addrconf.h>
#include <linux/if_arp.h>
@@ -116,6 +119,33 @@
static bool ecm_interface_terminate_pending = false; /* True when the user has signalled we should quit */
/*
+ * ecm_interface_get_and_hold_dev_master()
+ * Returns the master device of a net device if any.
+ */
+struct net_device *ecm_interface_get_and_hold_dev_master(struct net_device *dev)
+{
+ struct net_device *master;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,6,0))
+ rcu_read_lock();
+ master = netdev_master_upper_dev_get_rcu(dev);
+ if (!master) {
+ rcu_read_unlock();
+ return NULL;
+ }
+ dev_hold(master);
+ rcu_read_unlock();
+#else
+ master = dev->master;
+ if (!master) {
+ return NULL;
+ }
+ dev_hold(master);
+#endif
+ return master;
+}
+EXPORT_SYMBOL(ecm_interface_get_and_hold_dev_master);
+
+/*
* ecm_interface_dev_find_by_local_addr_ipv4()
* Return a hold to the device for the given local IP address. Returns NULL on failure.
*/
@@ -328,12 +358,17 @@
return false;
}
DEBUG_ASSERT(ecm_rt.v4_route, "Did not locate a v4 route!\n");
+ DEBUG_TRACE("Found route\n");
/*
* Is this destination on link or off-link via a gateway?
*/
rt = ecm_rt.rt.rtv4;
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
if ((rt->rt_dst != rt->rt_gateway) || (rt->rt_flags & RTF_GATEWAY)) {
+#else
+ if (rt->rt_uses_gateway || (rt->rt_flags & RTF_GATEWAY)) {
+#endif
*on_link = false;
ECM_NIN4_ADDR_TO_IP_ADDR(gw_addr, rt->rt_gateway)
} else {
@@ -345,27 +380,35 @@
*/
rcu_read_lock();
dst = ecm_rt.dst;
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
neigh = dst_get_neighbour_noref(dst);
if (neigh) {
neigh_hold(neigh);
- } else {
+ }
+#else
+ neigh = dst_neigh_lookup(dst, &ipv4_addr);
+#endif
+ if (!neigh) {
neigh = neigh_lookup(&arp_tbl, &ipv4_addr, dst->dev);
}
if (!neigh) {
rcu_read_unlock();
ecm_interface_route_release(&ecm_rt);
+ DEBUG_WARN("no neigh\n");
return false;
}
if (!(neigh->nud_state & NUD_VALID)) {
rcu_read_unlock();
neigh_release(neigh);
ecm_interface_route_release(&ecm_rt);
+ DEBUG_WARN("neigh nud state is not valid\n");
return false;
}
if (!neigh->dev) {
rcu_read_unlock();
neigh_release(neigh);
ecm_interface_route_release(&ecm_rt);
+ DEBUG_WARN("neigh has no device\n");
return false;
}
@@ -929,6 +972,7 @@
}
#ifdef CONFIG_IPV6_SIT_6RD
+#ifdef ECM_INTERFACE_SIT_ENABLE
/*
* ecm_interface_sit_interface_establish()
* Returns a reference to a iface of the SIT type, possibly creating one if necessary.
@@ -979,6 +1023,7 @@
return nii;
}
#endif
+#endif
/*
* ecm_interface_tunipip6_interface_establish()
@@ -1192,6 +1237,7 @@
}
#ifdef CONFIG_IPV6_SIT_6RD
+#ifdef ECM_INTERFACE_SIT_ENABLE
/*
* SIT (6-in-4)?
*/
@@ -1226,6 +1272,7 @@
return ii;
}
#endif
+#endif
/*
* IPIP6 Tunnel?
@@ -1685,14 +1732,14 @@
DEBUG_TRACE("Net device: %p is BRIDGE, next_dev: %p (%s)\n", dest_dev, next_dev, next_dev->name);
break;
}
-
+#ifdef ECM_INTERFACE_BOND_ENABLE
/*
* LAG?
*/
if (ecm_front_end_is_lag_master(dest_dev)) {
/*
* Link aggregation
- * Figure out which slave device of the link aggregation will be used to reach the destination.
+ * Figure out whiich slave device of the link aggregation will be used to reach the destination.
*/
bool dest_on_link = false;
ip_addr_t dest_gw_addr = ECM_IP_ADDR_NULL;
@@ -1712,11 +1759,14 @@
memcpy(src_mac_addr, src_node_addr, ETH_ALEN);
memcpy(dest_mac_addr, dest_node_addr, ETH_ALEN);
} else {
+ struct net_device *dest_dev_master;
+
/*
* Use appropriate source MAC address for routed packets
*/
- if (dest_dev->master) {
- memcpy(src_mac_addr, dest_dev->master->dev_addr, ETH_ALEN);
+ dest_dev_master = ecm_interface_get_and_hold_dev_master(dest_dev);
+ if (dest_dev_master) {
+ memcpy(src_mac_addr, dest_dev_master->dev_addr, ETH_ALEN);
} else {
memcpy(src_mac_addr, dest_dev->dev_addr, ETH_ALEN);
}
@@ -1739,14 +1789,18 @@
/*
* find proper interfce from which to issue ARP
*/
- if (dest_dev->master) {
- master_dev = dest_dev->master;
+ if (dest_dev_master) {
+ master_dev = dest_dev_master;
} else {
master_dev = dest_dev;
}
dev_hold(master_dev);
+ if (dest_dev_master) {
+ dev_put(dest_dev_master);
+ }
+
ECM_IP_ADDR_TO_NIN4_ADDR(ipv4_addr, dest_addr);
src_ip = inet_select_addr(master_dev, ipv4_addr, RT_SCOPE_LINK);
if (!src_ip) {
@@ -1780,6 +1834,10 @@
ecm_db_connection_interfaces_deref(interfaces, current_interface_index);
return ECM_DB_IFACE_HEIRARCHY_MAX;
}
+
+ if (dest_dev_master) {
+ dev_put(dest_dev_master);
+ }
}
next_dev = bond_get_tx_dev(NULL, src_mac_addr, dest_mac_addr,
@@ -1802,6 +1860,7 @@
DEBUG_TRACE("Net device: %p is LAG, slave dev: %p (%s)\n", dest_dev, next_dev, next_dev->name);
break;
}
+#endif
/*
* ETHERNET!
@@ -2256,7 +2315,11 @@
if (!netif_carrier_ok(dev)) {
DEBUG_INFO("Net device: %p, CARRIER BAD\n", dev);
if (netif_is_bond_slave(dev)) {
- ecm_interface_dev_regenerate_connections(dev->master);
+ struct net_device *master;
+ master = ecm_interface_get_and_hold_dev_master(dev);
+ DEBUG_ASSERT(master, "Expected a master\n");
+ ecm_interface_dev_regenerate_connections(master);
+ dev_put(master);
} else {
ecm_interface_dev_regenerate_connections(dev);
}
diff --git a/ecm_interface.h b/ecm_interface.h
index 31f9172..d91d88d 100644
--- a/ecm_interface.h
+++ b/ecm_interface.h
@@ -51,3 +51,4 @@
int32_t ecm_interface_heirarchy_construct(struct ecm_db_iface_instance *interfaces[], ip_addr_t packet_src_addr, ip_addr_t packet_dest_addr, int packet_protocol, struct net_device *given_dest_dev, bool is_routed, struct net_device *given_src_dev, uint8_t *dest_node_addr, uint8_t *src_node_addr);
void ecm_interface_stats_update(struct ecm_db_connection_instance *ci, uint32_t from_tx_packets, uint32_t from_tx_bytes, uint32_t from_rx_packets, uint32_t from_rx_bytes, uint32_t to_tx_packets, uint32_t to_tx_bytes, uint32_t to_rx_packets, uint32_t to_rx_bytes);
struct net_device *ecm_interface_dev_find_by_addr(ip_addr_t addr, bool *from_local_addr);
+struct net_device *ecm_interface_get_and_hold_dev_master(struct net_device *dev);
diff --git a/ecm_tracker.c b/ecm_tracker.c
index 5703c14..8c83f78 100644
--- a/ecm_tracker.c
+++ b/ecm_tracker.c
@@ -14,6 +14,7 @@
**************************************************************************
*/
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
diff --git a/ecm_tracker_datagram.c b/ecm_tracker_datagram.c
index 641cb79..1996d1e 100644
--- a/ecm_tracker_datagram.c
+++ b/ecm_tracker_datagram.c
@@ -14,6 +14,7 @@
**************************************************************************
*/
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
diff --git a/ecm_tracker_udp.c b/ecm_tracker_udp.c
index 5f14362..72edbba 100644
--- a/ecm_tracker_udp.c
+++ b/ecm_tracker_udp.c
@@ -14,6 +14,7 @@
**************************************************************************
*/
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/tcp.h>
diff --git a/ecm_types.h b/ecm_types.h
index c218269..c5c6d97 100644
--- a/ecm_types.h
+++ b/ecm_types.h
@@ -150,6 +150,7 @@
*/
#define ECM_IP_ADDR_TO_NIN4_ADDR(nin4, ipaddrt) \
{ \
+ nin4 = 0; \
ecm_nss_type_check_linux_ipv4(nin4); \
ecm_nss_type_check_ecm_ip_addr(ipaddrt); \
DEBUG_ASSERT(!ipaddrt[3] && !ipaddrt[2] && (ipaddrt[1] == 0x0000ffff), "Not IPv4 address: " ECM_IP_ADDR_OCTAL_FMT "\n", ECM_IP_ADDR_TO_OCTAL(ipaddrt)); \
@@ -233,6 +234,19 @@
}
/*
+ * ecm_mac_addr_equal()
+ * Compares two MAC addresses.
+ */
+static inline unsigned ecm_mac_addr_equal(const u8 *addr1, const u8 *addr2)
+{
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,6,0))
+ return compare_ether_addr(addr1, addr2);
+#else
+ return ether_addr_equal(addr1, addr2);
+#endif
+}
+
+/*
* ecm_ip_addr_is_non_unicast()
* Returns true if the IP address is not unicast
*/