Merge "IPACM: add conntrack optimization for lan2lan module"
diff --git a/ipacm/inc/IPACM_ConntrackClient.h b/ipacm/inc/IPACM_ConntrackClient.h
index 51855b6..ef0a2ca 100644
--- a/ipacm/inc/IPACM_ConntrackClient.h
+++ b/ipacm/inc/IPACM_ConntrackClient.h
@@ -75,37 +75,38 @@
{
private:
- static IPACM_ConntrackClient *pInstance;
+ static IPACM_ConntrackClient *pInstance;
- struct nfct_handle *tcp_hdl;
- struct nfct_handle *udp_hdl;
- struct nfct_filter *tcp_filter;
- struct nfct_filter *udp_filter;
-
- static int IPA_Conntrack_Filters_Ignore_Local_Addrs(struct nfct_filter *filter);
- static int IPA_Conntrack_Filters_Ignore_Bridge_Addrs(struct nfct_filter *filter);
- IPACM_ConntrackClient();
+ struct nfct_handle *tcp_hdl;
+ struct nfct_handle *udp_hdl;
+ struct nfct_filter *tcp_filter;
+ struct nfct_filter *udp_filter;
+ static int IPA_Conntrack_Filters_Ignore_Local_Addrs(struct nfct_filter *filter);
+ static int IPA_Conntrack_Filters_Ignore_Bridge_Addrs(struct nfct_filter *filter);
+ static int IPA_Conntrack_Filters_Ignore_Local_Iface(struct nfct_filter *, ipacm_event_iface_up *);
+ IPACM_ConntrackClient();
public:
- static int IPAConntrackEventCB(enum nf_conntrack_msg_type type,
- struct nf_conntrack *ct,
- void *data);
+ static int IPAConntrackEventCB(enum nf_conntrack_msg_type type,
+ struct nf_conntrack *ct,
+ void *data);
- static int IPA_Conntrack_UDP_Filter_Init(void);
- static int IPA_Conntrack_TCP_Filter_Init(void);
- static void* TCPRegisterWithConnTrack(void *);
- static void* UDPRegisterWithConnTrack(void *);
- static void* UDPConnTimeoutUpdate(void *);
- static void* TCPUDP_Timeout_monitor(void *);
+ static int IPA_Conntrack_UDP_Filter_Init(void);
+ static int IPA_Conntrack_TCP_Filter_Init(void);
+ static void* TCPRegisterWithConnTrack(void *);
+ static void* UDPRegisterWithConnTrack(void *);
+ static void* UDPConnTimeoutUpdate(void *);
+ static void* TCPUDP_Timeout_monitor(void *);
- static void UpdateUDPFilters(void *);
- static void UpdateTCPFilters(void *);
- static void Read_TcpUdp_Timeout(char *in, int len);
+ static void UpdateUDPFilters(void *, bool);
+ static void UpdateTCPFilters(void *, bool);
+ static void Read_TcpUdp_Timeout(char *in, int len);
- static IPACM_ConntrackClient* GetInstance();
+ static IPACM_ConntrackClient* GetInstance();
#ifdef IPACM_DEBUG
- static void iptodot(const char *type, uint32_t ipAddr);
+#define iptodot(X,Y) \
+ IPACMLOG(" %s(0x%x): %d.%d.%d.%d\n", X, Y, ((Y>>24) & 0xFF), ((Y>>16) & 0xFF), ((Y>>8) & 0xFF), (Y & 0xFF));
#endif
};
diff --git a/ipacm/inc/IPACM_ConntrackListener.h b/ipacm/inc/IPACM_ConntrackListener.h
index cc16f86..fc7282c 100644
--- a/ipacm/inc/IPACM_ConntrackListener.h
+++ b/ipacm/inc/IPACM_ConntrackListener.h
@@ -43,6 +43,9 @@
#include "IPACM_CmdQueue.h"
#include "IPACM_Conntrack_NATApp.h"
#include "IPACM_Listener.h"
+#ifdef CT_OPT
+#include "IPACM_LanToLan.h"
+#endif
#define MAX_NAT_IFACES 50
@@ -53,6 +56,7 @@
private:
bool isCTReg;
+ bool isNatThreadStart;
bool WanUp;
NatApp *nat_inst;
@@ -61,15 +65,23 @@
uint32_t nat_iface_ipv4_addr[MAX_NAT_IFACES];
uint32_t nonnat_iface_ipv4_addr[MAX_NAT_IFACES];
IPACM_Config *pConfig;
+#ifdef CT_OPT
+ IPACM_LanToLan *p_lan2lan;
+#endif
- void ProcessCTMessage(void *data);
- void ProcessTCPorUDPMsg(struct nf_conntrack *, enum nf_conntrack_msg_type, u_int8_t);
+ void ProcessCTMessage(void *);
+ void ProcessTCPorUDPMsg(struct nf_conntrack *,
+ enum nf_conntrack_msg_type, u_int8_t);
void TriggerWANUp(void *);
void TriggerWANDown(uint32_t);
int CreateNatThreads(void);
+ int CreateConnTrackThreads(void);
void HandleNeighIpAddrAddEvt(void *);
void HandleNeighIpAddrDelEvt(void *);
+#ifdef CT_OPT
+ void ProcessCTV6Message(void *);
+#endif
public:
char wan_ifname[IPA_IFACE_NAME_LEN];
@@ -80,8 +92,10 @@
void event_callback(ipa_cm_event_id, void *data);
inline bool isWanUp()
{
- return WanUp;
+ return WanUp;
}
};
+extern IPACM_ConntrackListener *CtList;
+
#endif /* IPACM_CONNTRACK_LISTENER */
diff --git a/ipacm/inc/IPACM_Defs.h b/ipacm/inc/IPACM_Defs.h
index 9b9a55b..b5adff3 100644
--- a/ipacm/inc/IPACM_Defs.h
+++ b/ipacm/inc/IPACM_Defs.h
@@ -51,7 +51,7 @@
#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h>
}
-
+#define IF_NAME_LEN 16
#define IPA_MAX_FILE_LEN 64
#define IPA_IFACE_NAME_LEN 16
#define IPA_ALG_PROTOCOL_NAME_LEN 10
@@ -92,6 +92,10 @@
#define IPA_LAN_TO_LAN_WLAN_HDR_NAME_V6 "Lan2Lan_Wlan_v6"
#define IPA_LAN_TO_LAN_MAX_WLAN_CLIENT 32
#define IPA_LAN_TO_LAN_MAX_USB_CLIENT 1
+#define TCP_FIN_SHIFT 16
+#define TCP_SYN_SHIFT 17
+#define TCP_RST_SHIFT 18
+#define NUM_TCP_CTL_FLT_RULE 3
/*---------------------------------------------------------------------------
Return values indicating error status
@@ -151,6 +155,7 @@
IPA_LAN_DELETE_SELF, /* 36 ipacm_event_data_fid */
IPA_WLAN_LINK_DOWN_EVENT, /* 37 ipacm_event_data_mac */
IPA_USB_LINK_UP_EVENT, /* 38 ipacm_event_data_fid */
+ IPA_PROCESS_CT_MESSAGE_V6, /* 39 ipacm_ct_evt_data */
IPACM_EVENT_MAX
} ipa_cm_event_id;
diff --git a/ipacm/inc/IPACM_Iface.h b/ipacm/inc/IPACM_Iface.h
index 2f36714..eb9e265 100644
--- a/ipacm/inc/IPACM_Iface.h
+++ b/ipacm/inc/IPACM_Iface.h
@@ -49,7 +49,6 @@
#include "IPACM_EvtDispatcher.h"
#include "IPACM_Xml.h"
#include "IPACM_Log.h"
-#include "IPACM_Netlink.h"
#include "IPACM_Config.h"
#include "IPACM_Defs.h"
diff --git a/ipacm/inc/IPACM_Lan.h b/ipacm/inc/IPACM_Lan.h
index 6c41863..7f5229e 100644
--- a/ipacm/inc/IPACM_Lan.h
+++ b/ipacm/inc/IPACM_Lan.h
@@ -177,6 +177,11 @@
/* store ipv6 UL filter rule handlers from Q6*/
uint32_t wan_ul_fl_rule_hdl_v6[MAX_WAN_UL_FILTER_RULES];
+ virtual void install_tcp_ctl_flt_rule(ipa_ip_type iptype);
+
+ uint32_t tcp_ctl_flt_rule_hdl_v4[NUM_TCP_CTL_FLT_RULE];
+ uint32_t tcp_ctl_flt_rule_hdl_v6[NUM_TCP_CTL_FLT_RULE];
+
int num_wan_ul_fl_rule_v4;
int num_wan_ul_fl_rule_v6;
diff --git a/ipacm/inc/IPACM_LanToLan.h b/ipacm/inc/IPACM_LanToLan.h
index dba7fd5..480f76c 100644
--- a/ipacm/inc/IPACM_LanToLan.h
+++ b/ipacm/inc/IPACM_LanToLan.h
@@ -97,6 +97,11 @@
IPACM_LanToLan();
~IPACM_LanToLan();
+ void handle_new_connection(ipacm_event_connection* new_conn);
+ void handle_del_connection(ipacm_event_connection* del_conn);
+
+ static IPACM_LanToLan* getLan2LanInstance();
+
private:
uint8_t num_offload_pair_v4_;
@@ -104,6 +109,8 @@
client_table_v4 client_info_v4_;
client_table_v6 client_info_v6_;
+ static IPACM_LanToLan* p_instance;
+
void event_callback(ipa_cm_event_id event, void* param);
void handle_client_active(ipacm_event_lan_client* data);
@@ -131,11 +138,12 @@
int add_flt_rules(ipa_ip_type iptype, client_info* client);
//the following are for connections
- void handle_new_connection(ipacm_event_connection* data);
+
+ void handle_new_lan2lan_connection(ipacm_event_connection* data);
bool add_connection(client_info* src_client, client_info* dst_client);
- void handle_del_connection(ipacm_event_connection* data);
+ void handle_del_lan2lan_connection(ipacm_event_connection* data);
bool remove_connection(client_info* src_client, client_info* dst_client);
@@ -143,6 +151,8 @@
void generate_new_connection(ipa_ip_type iptype, client_info* client);
+ bool is_lan2lan_connection(ipacm_event_connection* data);
+
};
#endif
diff --git a/ipacm/inc/IPACM_Log.h b/ipacm/inc/IPACM_Log.h
index 54be34a..c54d05b 100644
--- a/ipacm/inc/IPACM_Log.h
+++ b/ipacm/inc/IPACM_Log.h
@@ -59,8 +59,12 @@
#ifdef DEBUG
#define IPACMDBG(fmt, ...) syslog(LOG_DEBUG, "%s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);\
printf("%s:%d %s() " fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);
+
+#define IPACMLOG(fmt, ...) syslog(LOG_DEBUG, fmt, ##__VA_ARGS__);\
+ printf(fmt, ##__VA_ARGS__);
#else
#define IPACMDBG(fmt, ...)
+#define IPACMLOG(fmt, ...)
#endif
diff --git a/ipacm/inc/IPACM_Netlink.h b/ipacm/inc/IPACM_Netlink.h
index 8665407..d379031 100644
--- a/ipacm/inc/IPACM_Netlink.h
+++ b/ipacm/inc/IPACM_Netlink.h
@@ -60,8 +60,6 @@
#define MAX_NUM_OF_FD 10
#define IPA_NL_MSG_MAX_LEN (2048)
-#define IF_NAME_LEN 16
-
/*---------------------------------------------------------------------------
Type representing enumeration of NetLink event indication messages
diff --git a/ipacm/inc/IPACM_Wlan.h b/ipacm/inc/IPACM_Wlan.h
index b351a68..ce875e0 100644
--- a/ipacm/inc/IPACM_Wlan.h
+++ b/ipacm/inc/IPACM_Wlan.h
@@ -250,6 +250,8 @@
/* install UL filter rule from Q6 */
virtual int handle_uplink_filter_rule(ipacm_ext_prop* prop, ipa_ip_type iptype);
+
+ virtual void install_tcp_ctl_flt_rule(ipa_ip_type iptype);
};
diff --git a/ipacm/src/IPACM_Config.cpp b/ipacm/src/IPACM_Config.cpp
index bace803..c8d145a 100644
--- a/ipacm/src/IPACM_Config.cpp
+++ b/ipacm/src/IPACM_Config.cpp
@@ -263,6 +263,7 @@
if (res != IPACM_SUCCESS)
{
delete pInstance;
+ IPACMERR("unable to initialize config instance\n");
return NULL;
}
}
diff --git a/ipacm/src/IPACM_ConntrackClient.cpp b/ipacm/src/IPACM_ConntrackClient.cpp
index 75c4c2e..457e48a 100644
--- a/ipacm/src/IPACM_ConntrackClient.cpp
+++ b/ipacm/src/IPACM_ConntrackClient.cpp
@@ -43,31 +43,15 @@
#define LO_NAME "lo"
extern IPACM_EvtDispatcher cm_dis;
+extern void ParseCTMessage(struct nf_conntrack *ct);
-IPACM_ConntrackClient *IPACM_ConntrackClient::pInstance = IPACM_ConntrackClient::GetInstance();
-IPACM_ConntrackListener *CtList = new IPACM_ConntrackListener();
+IPACM_ConntrackClient *IPACM_ConntrackClient::pInstance = NULL;
+IPACM_ConntrackListener *CtList = NULL;
/* ================================
Local Function Definitions
=================================
*/
-#ifdef IPACM_DEBUG
-void IPACM_ConntrackClient::iptodot(const char *type, uint32_t ipAddr)
-{
- int i;
- unsigned char octet[4] = { 0 };
- IPACMDBG("Received IPv4 addr: 0x%x\n", ipAddr);
-
- for(i = 0; i < 4; i++)
- {
- octet[i] = (ipAddr >> (i * 8)) & 0xFF;
- }
-
- IPACMDBG("%s:", type);
- IPACMDBG("%d.%d.%d.%d\n", octet[3], octet[2], octet[1], octet[0]);
-}
-#endif
-
IPACM_ConntrackClient::IPACM_ConntrackClient()
{
IPACMDBG("\n");
@@ -106,7 +90,6 @@
return pInstance;
}
-extern void ParseCTMessage(struct nf_conntrack *ct);
int IPACM_ConntrackClient::IPAConntrackEventCB
(
enum nf_conntrack_msg_type type,
@@ -116,21 +99,34 @@
{
ipacm_cmd_q_data evt_data;
ipacm_ct_evt_data *ct_data;
+ uint8_t ip_type = 0;
IPACMDBG("Event callback called with msgtype: %d\n",type);
+ /* Retrieve ip type */
+ ip_type = nfct_get_attr_u8(ct, ATTR_REPL_L3PROTO);
+
+#ifndef CT_OPT
+ if(AF_INET6 == ip_type)
+ {
+ IPACMDBG("Ignoring ipv6(%d) connections\n", ip_type);
+ goto IGNORE;
+ }
+
if(!CtList->isWanUp())
{
#ifdef IPACM_DEBUG
+ IPACMDBG("Wan is not up, ignoring below connections\n");
char buf[1024];
nfct_snprintf(buf, sizeof(buf), ct,
type, NFCT_O_PLAIN, NFCT_OF_TIME);
- IPACMDBG("%s\n", buf);
- IPACMDBG("\n");
+ IPACMDBG("%s\n", buf);
+ IPACMDBG("\n");
ParseCTMessage(ct);
#endif
goto IGNORE;
}
+#endif
ct_data = (ipacm_ct_evt_data *)malloc(sizeof(ipacm_ct_evt_data));
if(ct_data == NULL)
@@ -145,6 +141,13 @@
evt_data.event = IPA_PROCESS_CT_MESSAGE;
evt_data.evt_data = (void *)ct_data;
+#ifdef CT_OPT
+ if(AF_INET6 == ip_type)
+ {
+ evt_data.event = IPA_PROCESS_CT_MESSAGE_V6;
+ }
+#endif
+
if(0 != IPACM_EvtDispatcher::PostEvt(&evt_data))
{
IPACMERR("Error sending Conntrack message to processing thread!\n");
@@ -215,6 +218,56 @@
return 0;
}
+int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Local_Iface
+(
+ struct nfct_filter *filter,
+ ipacm_event_iface_up *param
+)
+{
+ struct nfct_filter_ipv4 filter_ipv4;
+
+ filter_ipv4.addr = param->ipv4_addr;
+ filter_ipv4.mask = 0xffffffff;
+
+ /* ignore whatever is destined to local interfaces */
+ IPACMDBG("Ignore connections destinated to interface %s", param->ifname);
+ iptodot("with ipv4 address", param->ipv4_addr);
+ nfct_filter_set_logic(filter,
+ NFCT_FILTER_DST_IPV4,
+ NFCT_FILTER_LOGIC_NEGATIVE);
+
+ nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
+
+ IPACMDBG("Ignore connections orignated from interface %s", param->ifname);
+ iptodot("with ipv4 address", filter_ipv4.addr);
+ nfct_filter_set_logic(filter,
+ NFCT_FILTER_SRC_IPV4,
+ NFCT_FILTER_LOGIC_NEGATIVE);
+
+ nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
+
+ /* Retrieve broadcast address */
+ /* Intialize with 255.255.255.255 */
+ uint32_t bc_ip_addr = 0xFFFFFFFF;
+
+ /* calculate broadcast address from addr and addr_mask */
+ bc_ip_addr = (bc_ip_addr & (~param->addr_mask));
+ bc_ip_addr = (bc_ip_addr | (param->ipv4_addr & param->addr_mask));
+
+ /* netfitler expecting in host-byte order */
+ filter_ipv4.addr = bc_ip_addr;
+ filter_ipv4.mask = 0xffffffff;
+
+ iptodot("with broadcast address", filter_ipv4.addr);
+ nfct_filter_set_logic(filter,
+ NFCT_FILTER_DST_IPV4,
+ NFCT_FILTER_LOGIC_NEGATIVE);
+
+ nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
+
+ return 0;
+}
+
/* Function which sets up filters to ignore
connections to and from local interfaces */
int IPACM_ConntrackClient::IPA_Conntrack_Filters_Ignore_Local_Addrs
@@ -222,10 +275,6 @@
struct nfct_filter *filter
)
{
- char buf[1024];
- struct ifconf ifc;
- struct ifreq *ifr;
- int i, sck, nInterfaces;
struct nfct_filter_ipv4 filter_ipv4;
/* ignore whatever is destined to or originates from broadcast ip address */
@@ -244,124 +293,6 @@
nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
-
-
- /* Get a socket handle. */
- sck = socket(AF_INET, SOCK_DGRAM, 0);
- if(sck < 0)
- {
- PERROR("socket");
- return -1;
- }
-
- /* Query available interfaces. */
- ifc.ifc_len = sizeof(buf);
- ifc.ifc_buf = buf;
-
- /* get iface list */
- if(ioctl(sck, SIOCGIFCONF, &ifc) < 0)
- {
- PERROR("ioctl(SIOCGIFCONF)");
- close(sck);
- return -1;
- }
-
- /* Iterate through the list of interfaces. */
- ifr = ifc.ifc_req;
- nInterfaces = ifc.ifc_len / sizeof(struct ifreq);
-
-#ifdef IPACM_DEBUG
- IPACMDBG("====Printing Local Interfaces=====\n");
-#endif
-
- for(i = 0; i < nInterfaces; i++)
- {
- /* Interface request structure */
- struct ifreq *item = &ifr[i];
-
-#ifdef IPACM_DEBUG
- /* Show the device name and IP address */
- if(item->ifr_name != NULL)
- {
- IPACMDBG("%s: IP %s\n",
- item->ifr_name,
- inet_ntoa(((struct sockaddr_in *)&item->ifr_addr)->sin_addr));
- }
-#endif
-
- /* Convert data to host-byte order */
- filter_ipv4.addr =
- ntohl(inet_addr(inet_ntoa(((struct sockaddr_in *)&item->ifr_addr)->sin_addr)));
- filter_ipv4.mask = 0xffffffff;
-
- if(item->ifr_name != NULL)
- {
- /* check whether interface is non wan iface */
- if(strncmp(CtList->wan_ifname, item->ifr_name, strlen(item->ifr_name)) != 0)
- {
- /* ignore whatever is destined to local interfaces */
- IPACMDBG("ignore connections destinated to interface %s\n", item->ifr_name);
- IPACM_ConntrackClient::iptodot("with ipv4 address:", filter_ipv4.addr);
- nfct_filter_set_logic(filter,
- NFCT_FILTER_DST_IPV4,
- NFCT_FILTER_LOGIC_NEGATIVE);
-
- nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
-
- /* In AP+STA mode only listen to connections orignated from local interface */
- if(!CtList->isStaMode) {
- IPACMDBG("ignore connections orignated from interface %s\n", item->ifr_name);
- IPACM_ConntrackClient::iptodot("with ipv4 address:", filter_ipv4.addr);
- nfct_filter_set_logic(filter,
- NFCT_FILTER_SRC_IPV4,
- NFCT_FILTER_LOGIC_NEGATIVE);
-
- nfct_filter_add_attr(filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
- }
-
- }
- }
-
- /* Find broadcast address for non lo interfaces */
- if(strncmp(LO_NAME, item->ifr_name, 2) != 0)
- {
- /* Get the broadcast address */
- if(ioctl(sck, SIOCGIFBRDADDR, item) < 0)
- {
- PERROR("broadcast address error: ioctl(SIOCGIFBRDADDR)");
- close(sck);
- return -1;
- }
-
-#ifdef IPACM_DEBUG
- /* Show the device name and IP address */
- if(item->ifr_name != NULL)
- {
- IPACMDBG("%s: BroadCast IP %s\n",
- item->ifr_name,
- inet_ntoa(((struct sockaddr_in *)&item->ifr_broadaddr)->sin_addr));
- }
-#endif
-
- /* Convert data to host-byte order */
- filter_ipv4.addr =
- ntohl(inet_addr(inet_ntoa(((struct sockaddr_in *)&item->ifr_broadaddr)->sin_addr)));
- filter_ipv4.mask = 0xffffffff;
-
- IPACMDBG("ignore connections destinated to interface %s broadcast\n", item->ifr_name);
- IPACM_ConntrackClient::iptodot("with ipv4 address:", filter_ipv4.addr);
- nfct_filter_set_logic(filter,
- NFCT_FILTER_DST_IPV4,
- NFCT_FILTER_LOGIC_NEGATIVE);
-
- nfct_filter_add_attr(filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
- }
-
- }
-
- close(sck);
- IPA_Conntrack_Filters_Ignore_Bridge_Addrs(filter);
-
return 0;
} /* IPA_Conntrack_Filters_Ignore_Local_Addrs() */
@@ -380,13 +311,6 @@
return -1;
}
- ret = IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->tcp_filter);
- if(ret == -1)
- {
- IPACMERR("Unable to set local addr filters\n");
- return -1;
- }
-
ret = nfct_filter_set_logic(pClient->tcp_filter,
NFCT_FILTER_L4PROTO,
NFCT_FILTER_LOGIC_POSITIVE);
@@ -440,11 +364,9 @@
{
int ret = 0;
IPACM_ConntrackClient *pClient = IPACM_ConntrackClient::GetInstance();
-
- ret = IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
- if(ret == -1)
+ if(pClient == NULL)
{
- IPACMERR("Unable to set local addr filters\n");
+ IPACMERR("unable to get conntrack client instance\n");
return -1;
}
@@ -494,6 +416,7 @@
{
int ret;
IPACM_ConntrackClient *pClient;
+ unsigned subscrips = 0;
IPACMDBG("\n");
@@ -504,24 +427,18 @@
return NULL;
}
- pClient->tcp_hdl = nfct_open(CONNTRACK,
- (NF_NETLINK_CONNTRACK_UPDATE |NF_NETLINK_CONNTRACK_DESTROY));
+ subscrips = (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
+#ifdef CT_OPT
+ subscrips |= NF_NETLINK_CONNTRACK_NEW;
+#endif
+
+ pClient->tcp_hdl = nfct_open(CONNTRACK, subscrips);
if(pClient->tcp_hdl == NULL)
{
PERROR("nfct_open\n");
return NULL;
}
- /* Allocate new filter */
- #if 0
- pClient->tcp_filter = nfct_filter_create();
- if(pClient->tcp_filter == NULL)
- {
- IPACMERR("unable to create TCP filter\n");
- return NULL;
- }
- #endif
-
/* Initialize the filter */
ret = IPA_Conntrack_TCP_Filter_Init();
if(ret == -1)
@@ -531,8 +448,7 @@
}
/* Attach the filter to net filter handler */
- ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl),
- pClient->tcp_filter);
+ ret = nfct_filter_attach(nfct_fd(pClient->tcp_hdl), pClient->tcp_filter);
if(ret == -1)
{
IPACMDBG("unable to attach TCP filter\n");
@@ -541,8 +457,13 @@
/* Register callback with netfilter handler */
IPACMDBG("tcp handle:%p, fd:%d\n", pClient->tcp_hdl, nfct_fd(pClient->tcp_hdl));
+#ifndef CT_OPT
nfct_callback_register(pClient->tcp_hdl,
- (NFCT_T_UPDATE | NFCT_T_DESTROY), IPAConntrackEventCB, NULL);
+ (NFCT_T_UPDATE | NFCT_T_DESTROY | NFCT_T_NEW),
+ IPAConntrackEventCB, NULL);
+#else
+ nfct_callback_register(pClient->tcp_hdl, NFCT_T_ALL, IPAConntrackEventCB, NULL);
+#endif
/* Block to catch events from net filter connection track */
/* nfct_catch() receives conntrack events from kernel-space, by default it
@@ -619,7 +540,7 @@
NULL);
/* Block to catch events from net filter connection track */
- ctcatch:
+ctcatch:
ret = nfct_catch(pClient->udp_hdl);
if(ret == -1)
{
@@ -648,21 +569,12 @@
return NULL;
}
-void IPACM_ConntrackClient::UpdateUDPFilters(void *param)
+void IPACM_ConntrackClient::UpdateUDPFilters(void *param, bool isWan)
{
+ static bool isIgnore = false;
int ret = 0;
- struct nfct_filter_ipv4 filter_ipv4;
IPACM_ConntrackClient *pClient = NULL;
- /* Intialize with 255.255.255.255 */
- uint32_t bc_ip_addr = 0xFFFFFFFF;
-
- uint32_t ipv4_addr = ((ipacm_event_iface_up *)param)->ipv4_addr;
- uint32_t ipv4_addr_mask = ((ipacm_event_iface_up *)param)->addr_mask;
-
- IPACM_ConntrackClient::iptodot("Received ipv4 address and", ipv4_addr);
- IPACM_ConntrackClient::iptodot("ipv4 address mask", ipv4_addr_mask);
-
pClient = IPACM_ConntrackClient::GetInstance();
if(pClient == NULL)
{
@@ -670,43 +582,22 @@
return;
}
- /* calculate broadcast address from addr and addr_mask */
- bc_ip_addr = (bc_ip_addr & (~ipv4_addr_mask));
- bc_ip_addr = (bc_ip_addr | (ipv4_addr & ipv4_addr_mask));
-
- /* netfitler expecting in host-byte order */
- filter_ipv4.addr = ipv4_addr;
- filter_ipv4.mask = 0xffffffff;
-
- IPACMDBG("ignoring interface:%s", ((ipacm_event_iface_up *)param)->ifname);
- IPACM_ConntrackClient::iptodot("with ipv4 address", filter_ipv4.addr);
- if(pClient->udp_filter != NULL)
+ if(pClient->udp_filter == NULL)
{
- nfct_filter_set_logic(pClient->udp_filter,
- NFCT_FILTER_DST_IPV4,
- NFCT_FILTER_LOGIC_NEGATIVE);
-
- nfct_filter_add_attr(pClient->udp_filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
-
- nfct_filter_set_logic(pClient->udp_filter,
- NFCT_FILTER_SRC_IPV4,
- NFCT_FILTER_LOGIC_NEGATIVE);
-
- nfct_filter_add_attr(pClient->udp_filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
+ return;
}
- /* netfitler expecting in host-byte order */
- filter_ipv4.addr = bc_ip_addr;
- filter_ipv4.mask = 0xffffffff;
-
- IPACM_ConntrackClient::iptodot("with broadcast address", filter_ipv4.addr);
- if(pClient->udp_filter != NULL)
+ if(!isWan)
{
- nfct_filter_set_logic(pClient->udp_filter,
- NFCT_FILTER_DST_IPV4,
- NFCT_FILTER_LOGIC_NEGATIVE);
+ IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->udp_filter,
+ (ipacm_event_iface_up *)param);
- nfct_filter_add_attr(pClient->udp_filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
+ if(!isIgnore)
+ {
+ IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
+ IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
+ isIgnore = true;
+ }
}
/* Attach the filter to udp handle */
@@ -725,15 +616,11 @@
return;
}
-void IPACM_ConntrackClient::UpdateTCPFilters(void *param)
+void IPACM_ConntrackClient::UpdateTCPFilters(void *param, bool isWan)
{
+ static bool isIgnore = false;
int ret = 0;
- uint32_t ipv4_addr = ((ipacm_event_iface_up *)param)->ipv4_addr;
- uint32_t ipv4_addr_mask = ((ipacm_event_iface_up *)param)->addr_mask;
- struct nfct_filter_ipv4 filter_ipv4;
IPACM_ConntrackClient *pClient = NULL;
- /* Intialize with 255.255.255.255 */
- uint32_t bc_ip_addr = 0xFFFFFFFF;
pClient = IPACM_ConntrackClient::GetInstance();
if(pClient == NULL)
@@ -742,44 +629,20 @@
return;
}
- /* calculate broadcast address from addr and addr_mask */
- bc_ip_addr = (bc_ip_addr & (~ipv4_addr_mask));
- bc_ip_addr = (bc_ip_addr | (ipv4_addr & ipv4_addr_mask));
+ if(pClient->tcp_filter == NULL)
+ return;
- /* netfitler expecting in host-byte order */
- filter_ipv4.addr = ipv4_addr;
- filter_ipv4.mask = 0xffffffff;
-
- IPACMDBG("ignoring interface:%s", ((ipacm_event_iface_up *)param)->ifname);
- IPACM_ConntrackClient::iptodot("with ipv4 address", filter_ipv4.addr);
-
- if(pClient->tcp_filter != NULL)
+ if(!isWan)
{
- nfct_filter_set_logic(pClient->tcp_filter,
- NFCT_FILTER_DST_IPV4,
- NFCT_FILTER_LOGIC_NEGATIVE);
+ IPA_Conntrack_Filters_Ignore_Local_Iface(pClient->tcp_filter,
+ (ipacm_event_iface_up *)param);
- nfct_filter_add_attr(pClient->tcp_filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
-
- nfct_filter_set_logic(pClient->tcp_filter,
- NFCT_FILTER_SRC_IPV4,
- NFCT_FILTER_LOGIC_NEGATIVE);
-
- nfct_filter_add_attr(pClient->tcp_filter, NFCT_FILTER_SRC_IPV4, &filter_ipv4);
- }
-
- /* netfitler expecting in host-byte order */
- filter_ipv4.addr = bc_ip_addr;
- filter_ipv4.mask = 0xffffffff;
-
- IPACM_ConntrackClient::iptodot("with broadcast address", filter_ipv4.addr);
- if(pClient->tcp_filter != NULL)
- {
- nfct_filter_set_logic(pClient->tcp_filter,
- NFCT_FILTER_DST_IPV4,
- NFCT_FILTER_LOGIC_NEGATIVE);
-
- nfct_filter_add_attr(pClient->tcp_filter, NFCT_FILTER_DST_IPV4, &filter_ipv4);
+ if(!isIgnore)
+ {
+ IPA_Conntrack_Filters_Ignore_Bridge_Addrs(pClient->udp_filter);
+ IPA_Conntrack_Filters_Ignore_Local_Addrs(pClient->udp_filter);
+ isIgnore = true;
+ }
}
/* Attach the filter to tcp handle */
@@ -810,7 +673,7 @@
if(nat_inst == NULL)
{
IPACMERR("unable to create nat instance\n");
- return NULL;
+ return;
}
if(!strncmp(in, IPACM_TCP_FILE_NAME, len))
@@ -834,7 +697,7 @@
{
fd = fopen(IPACM_UDP_FULL_FILE_NAME, "r");
}
- if(fd < 0)
+ if(fd == NULL)
{
PERROR("unable to open file");
return;
@@ -869,7 +732,7 @@
}
to_fd = fopen(IPACM_TCP_FULL_FILE_NAME, "r");
- if(to_fd < 0)
+ if(to_fd == NULL)
{
PERROR("unable to open file \"ip_conntrack_tcp_timeout_established\" ");
return NULL;
@@ -882,7 +745,7 @@
fclose(to_fd);
to_fd = fopen(IPACM_UDP_FULL_FILE_NAME, "r");
- if(to_fd < 0)
+ if(to_fd == NULL)
{
PERROR("unable to open file \"ip_conntrack_udp_timeout_stream\" ");
return NULL;
diff --git a/ipacm/src/IPACM_ConntrackListener.cpp b/ipacm/src/IPACM_ConntrackListener.cpp
index c5f94a2..0d53841 100644
--- a/ipacm/src/IPACM_ConntrackListener.cpp
+++ b/ipacm/src/IPACM_ConntrackListener.cpp
@@ -1,4 +1,4 @@
-/*
+/*
Copyright (c) 2013, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@
{
IPACMDBG("\n");
+ isNatThreadStart = false;
isCTReg = false;
WanUp = false;
nat_inst = NatApp::GetInstance();
@@ -52,9 +53,18 @@
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_UP, this);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WAN_DOWN, this);
IPACM_EvtDispatcher::registr(IPA_PROCESS_CT_MESSAGE, this);
+ IPACM_EvtDispatcher::registr(IPA_PROCESS_CT_MESSAGE_V6, this);
IPACM_EvtDispatcher::registr(IPA_HANDLE_WLAN_UP, this);
+ IPACM_EvtDispatcher::registr(IPA_HANDLE_LAN_UP, this);
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT, this);
IPACM_EvtDispatcher::registr(IPA_NEIGH_CLIENT_IP_ADDR_DEL_EVENT, this);
+
+ IPACMDBG("creating conntrack threads\n");
+ CreateConnTrackThreads();
+
+#ifdef CT_OPT
+ p_lan2lan = IPACM_LanToLan::getLan2LanInstance();
+#endif
}
void IPACM_ConntrackListener::event_callback(ipa_cm_event_id evt,
@@ -75,6 +85,13 @@
ProcessCTMessage(data);
break;
+#ifdef CT_OPT
+ case IPA_PROCESS_CT_MESSAGE_V6:
+ IPACMDBG("Received IPA_PROCESS_CT_MESSAGE_V6 event\n");
+ ProcessCTV6Message(data);
+ break;
+#endif
+
case IPA_HANDLE_WAN_UP:
IPACMDBG("Received IPA_HANDLE_WAN_UP event\n");
if(!isWanUp())
@@ -96,13 +113,12 @@
tcp/udp filters to ignore local wlan or lan connections */
case IPA_HANDLE_WLAN_UP:
case IPA_HANDLE_LAN_UP:
- IPACMDBG("Received event: %d\n", evt);
- if(isWanUp())
- {
- IPACM_ConntrackClient::UpdateUDPFilters(data);
- IPACM_ConntrackClient::UpdateTCPFilters(data);
- }
- break;
+ IPACMDBG("Received event: %d with ifname: %s and address: 0x%x\n",
+ evt, ((ipacm_event_iface_up *)data)->ifname,
+ ((ipacm_event_iface_up *)data)->ipv4_addr);
+ IPACM_ConntrackClient::UpdateUDPFilters(data, false);
+ IPACM_ConntrackClient::UpdateTCPFilters(data, false);
+ break;
case IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT:
{
@@ -123,7 +139,6 @@
break;
}
}
-
void IPACM_ConntrackListener::HandleNeighIpAddrAddEvt(void *in_param)
{
ipacm_event_data_all *data = (ipacm_event_data_all *)in_param;
@@ -136,8 +151,8 @@
IPACMDBG("Ignoring IPA_NEIGH_CLIENT_IP_ADDR_ADD_EVENT EVENT\n");
return;
}
- IPACMDBG("Received interface index %d with ip type:%d", data->if_index, data->iptype);
- IPACM_ConntrackClient::iptodot("and received ipv4 address", data->ipv4_addr);
+ IPACMDBG("Received interface index %d with ip type: %d", data->if_index, data->iptype);
+ iptodot(" and ipv4 address", data->ipv4_addr);
if(pConfig == NULL)
{
@@ -219,9 +234,16 @@
}
}
+ if(j == MAX_NAT_IFACES)
+ {
+ IPACMERR("Nat ifaces(%d) exceed maximum\n", j);
+ break;
+ }
+
+
isNatIface = true;
- IPACMDBG("Nating connections of Interface (%s), entry (%d)\n", pNatIfaces[i].iface_name, j);
- IPACM_ConntrackClient::iptodot("with ipv4 address", nat_iface_ipv4_addr[j]);
+ IPACMDBG("Nating connections of Interface (%s), entry (%d) ", pNatIfaces[i].iface_name, j);
+ iptodot("with ipv4 address", nat_iface_ipv4_addr[j]);
break;
}
}
@@ -259,15 +281,15 @@
{
if(nat_iface_ipv4_addr[cnt] == data->ipv4_addr)
{
- IPACMDBG("Reseting ct filters of Interface (%d), entry (%d)\n", data->if_index, cnt);
- IPACM_ConntrackClient::iptodot("with ipv4 address", nat_iface_ipv4_addr[cnt]);
+ IPACMDBG("Reseting ct filters of Interface (%d), entry (%d) ", data->if_index, cnt);
+ iptodot("with ipv4 address", nat_iface_ipv4_addr[cnt]);
nat_iface_ipv4_addr[cnt] = 0;
}
if(nonnat_iface_ipv4_addr[cnt] == data->ipv4_addr)
{
- IPACMDBG("Reseting ct filters of Interface (%d), entry (%d)\n", data->if_index, cnt);
- IPACM_ConntrackClient::iptodot("with ipv4 address", nonnat_iface_ipv4_addr[cnt]);
+ IPACMDBG("Reseting ct filters of Interface (%d), entry (%d) ", data->if_index, cnt);
+ iptodot("with ipv4 address", nonnat_iface_ipv4_addr[cnt]);
nonnat_iface_ipv4_addr[cnt] = 0;
}
}
@@ -280,7 +302,7 @@
{
ipacm_event_iface_up *wanup_data = (ipacm_event_iface_up *)in_param;
- IPACMDBG("Recevied below informatoin during wanup:\n");
+ IPACMDBG("Recevied below information during wanup, ");
IPACMDBG("if_name:%s, ipv4_address:0x%x\n",
wanup_data->ifname, wanup_data->ipv4_addr);
@@ -290,7 +312,6 @@
return;
}
- IPACM_ConntrackClient::iptodot("public ip address", wanup_data->ipv4_addr);
WanUp = true;
isStaMode = wanup_data->is_sta;
IPACMDBG("isStaMode: %d\n", isStaMode);
@@ -307,10 +328,10 @@
CreateNatThreads();
}
-int IPACM_ConntrackListener::CreateNatThreads(void)
+int IPACM_ConntrackListener::CreateConnTrackThreads(void)
{
int ret;
- pthread_t tcp_thread = 0, udp_thread = 0, udpcto_thread = 0, to_monitor_thread = 0;
+ pthread_t tcp_thread = 0, udp_thread = 0;
if(isCTReg == false)
{
@@ -341,6 +362,32 @@
IPACMDBG("created UDP conntrack event listner thread\n");
}
+ isCTReg = true;
+ }
+
+ return 0;
+
+error:
+ if(tcp_thread)
+ {
+ pthread_cancel(tcp_thread);
+ }
+
+ if(udp_thread)
+ {
+ pthread_cancel(tcp_thread);
+ }
+
+ return -1;
+}
+int IPACM_ConntrackListener::CreateNatThreads(void)
+{
+ int ret;
+ pthread_t udpcto_thread = 0, to_monitor_thread = 0;
+
+ if(isNatThreadStart == false)
+ {
+
if(!udpcto_thread)
{
ret = pthread_create(&udpcto_thread, NULL, IPACM_ConntrackClient::UDPConnTimeoutUpdate, NULL);
@@ -367,21 +414,11 @@
IPACMDBG("created tcp/udp timeout monitor thread\n");
}
- isCTReg = true;
+ isNatThreadStart = true;
}
return 0;
error:
- if(tcp_thread)
- {
- pthread_cancel(tcp_thread);
- }
-
- if(udp_thread)
- {
- pthread_cancel(tcp_thread);
- }
-
if(udpcto_thread)
{
pthread_cancel(udpcto_thread);
@@ -397,8 +434,8 @@
void IPACM_ConntrackListener::TriggerWANDown(uint32_t wan_addr)
{
- IPACMDBG("Deleting ipv4 nat table with ");
- IPACM_ConntrackClient::iptodot("public ip address", wan_addr);
+ IPACMDBG("Deleting ipv4 nat table with");
+ iptodot("public ip address", wan_addr);
WanUp = false;
if(nat_inst != NULL)
@@ -410,21 +447,21 @@
void ParseCTMessage(struct nf_conntrack *ct)
{
- uint32_t status;
+ uint32_t status, timeout;
IPACMDBG("Printing conntrack parameters\n");
- IPACM_ConntrackClient::iptodot("ATTR_IPV4_SRC = ATTR_ORIG_IPV4_SRC:", nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC));
- IPACM_ConntrackClient::iptodot("ATTR_IPV4_DST = ATTR_ORIG_IPV4_DST:", nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST));
+ iptodot("ATTR_IPV4_SRC = ATTR_ORIG_IPV4_SRC:", nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC));
+ iptodot("ATTR_IPV4_DST = ATTR_ORIG_IPV4_DST:", nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_DST));
IPACMDBG("ATTR_PORT_SRC = ATTR_ORIG_PORT_SRC: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC));
IPACMDBG("ATTR_PORT_DST = ATTR_ORIG_PORT_DST: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST));
- IPACM_ConntrackClient::iptodot("ATTR_REPL_IPV4_SRC:", nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC));
- IPACM_ConntrackClient::iptodot("ATTR_REPL_IPV4_DST:", nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST));
+ iptodot("ATTR_REPL_IPV4_SRC:", nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC));
+ iptodot("ATTR_REPL_IPV4_DST:", nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST));
IPACMDBG("ATTR_REPL_PORT_SRC: 0x%x\n", nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC));
IPACMDBG("ATTR_REPL_PORT_DST: 0x%x\n", nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST));
- IPACM_ConntrackClient::iptodot("ATTR_SNAT_IPV4:", nfct_get_attr_u32(ct, ATTR_SNAT_IPV4));
- IPACM_ConntrackClient::iptodot("ATTR_DNAT_IPV4:", nfct_get_attr_u32(ct, ATTR_DNAT_IPV4));
+ iptodot("ATTR_SNAT_IPV4:", nfct_get_attr_u32(ct, ATTR_SNAT_IPV4));
+ iptodot("ATTR_DNAT_IPV4:", nfct_get_attr_u32(ct, ATTR_DNAT_IPV4));
IPACMDBG("ATTR_SNAT_PORT: 0x%x\n", nfct_get_attr_u16(ct, ATTR_SNAT_PORT));
IPACMDBG("ATTR_DNAT_PORT: 0x%x\n", nfct_get_attr_u16(ct, ATTR_DNAT_PORT));
@@ -435,6 +472,9 @@
status = nfct_get_attr_u32(ct, ATTR_STATUS);
IPACMDBG("ATTR_STATUS: 0x%x\n", status);
+ timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT);
+ IPACMDBG("ATTR_TIMEOUT: 0x%x\n", timeout);
+
if(IPS_SRC_NAT & status)
{
IPACMDBG("IPS_SRC_NAT set\n");
@@ -459,10 +499,55 @@
return;
}
-void IPACM_ConntrackListener::ProcessCTMessage(void *param)
+void ParseCTV6Message(struct nf_conntrack *ct)
{
- ipacm_ct_evt_data *evt_data = (ipacm_ct_evt_data *)param;
- u_int8_t l4proto = 0;
+ uint32_t status, timeout, secmark;
+ struct nfct_attr_grp_ipv6 orig_params;
+ uint8_t l4proto, tcp_flags, tcp_state;
+
+ IPACMDBG("Printing conntrack parameters\n");
+
+ nfct_get_attr_grp(ct, ATTR_GRP_ORIG_IPV6, (void *)&orig_params);
+ IPACMDBG("Orig src_v6_addr: 0x%08x%08x%08x%08x\n", orig_params.src[0], orig_params.src[1],
+ orig_params.src[2], orig_params.src[3]);
+ IPACMDBG("Orig dst_v6_addr: 0x%08x%08x%08x%08x\n", orig_params.dst[0], orig_params.dst[1],
+ orig_params.dst[2], orig_params.dst[3]);
+
+ IPACMDBG("ATTR_PORT_SRC = ATTR_ORIG_PORT_SRC: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC));
+ IPACMDBG("ATTR_PORT_DST = ATTR_ORIG_PORT_DST: 0x%x\n", nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST));
+
+ IPACMDBG("ATTR_MARK: 0x%x\n", nfct_get_attr_u32(ct, ATTR_MARK));
+ IPACMDBG("ATTR_USE: 0x%x\n", nfct_get_attr_u32(ct, ATTR_USE));
+ IPACMDBG("ATTR_ID: 0x%x\n", nfct_get_attr_u32(ct, ATTR_ID));
+
+ timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT);
+ IPACMDBG("ATTR_TIMEOUT: 0x%x\n", timeout);
+
+ status = nfct_get_attr_u32(ct, ATTR_STATUS);
+ IPACMDBG("ATTR_STATUS: 0x%x\n", status);
+
+ l4proto = nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO);
+ IPACMDBG("ATTR_ORIG_L4PROTO: 0x%x\n", l4proto);
+ if(l4proto == IPPROTO_TCP)
+ {
+ tcp_state = nfct_get_attr_u8(ct, ATTR_TCP_STATE);
+ IPACMDBG("ATTR_TCP_STATE: 0x%x\n", tcp_state);
+
+ tcp_flags = nfct_get_attr_u8(ct, ATTR_TCP_FLAGS_ORIG);
+ IPACMDBG("ATTR_TCP_FLAGS_ORIG: 0x%x\n", tcp_flags);
+ }
+
+ IPACMDBG("\n");
+ return;
+}
+
+#ifdef CT_OPT
+void IPACM_ConntrackListener::ProcessCTV6Message(void *param)
+{
+ ipacm_ct_evt_data *evt_data = (ipacm_ct_evt_data *)param;
+ u_int8_t l4proto = 0;
+ uint32_t status = 0;
+ struct nf_conntrack *ct = evt_data->ct;
#ifdef IPACM_DEBUG
char buf[1024];
@@ -472,6 +557,93 @@
evt_data->type, NFCT_O_PLAIN, NFCT_OF_TIME);
IPACMDBG("%s\n", buf);
IPACMDBG("\n");
+ ParseCTV6Message(ct);
+#endif
+
+ if(p_lan2lan == NULL)
+ {
+ IPACMERR("Lan2Lan Instance is null\n");
+ goto IGNORE;
+ }
+
+ status = nfct_get_attr_u32(ct, ATTR_STATUS);
+ if((IPS_DST_NAT & status) || (IPS_SRC_NAT & status))
+ {
+ IPACMDBG("Either Destination or Source nat flag Set\n");
+ goto IGNORE;
+ }
+
+ l4proto = nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO);
+ if(IPPROTO_UDP != l4proto && IPPROTO_TCP != l4proto)
+ {
+ IPACMDBG("Received unexpected protocl %d conntrack message\n", l4proto);
+ goto IGNORE;
+ }
+
+ IPACMDBG("Neither Destination nor Source nat flag Set\n");
+ struct nfct_attr_grp_ipv6 orig_params;
+ nfct_get_attr_grp(ct, ATTR_GRP_ORIG_IPV6, (void *)&orig_params);
+
+ ipacm_event_connection lan2lan_conn;
+ lan2lan_conn.iptype = IPA_IP_v6;
+ memcpy(lan2lan_conn.src_ipv6_addr, orig_params.src,
+ sizeof(lan2lan_conn.src_ipv6_addr));
+ IPACMDBG("Before convert, src_v6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.src_ipv6_addr[0], lan2lan_conn.src_ipv6_addr[1],
+ lan2lan_conn.src_ipv6_addr[2], lan2lan_conn.src_ipv6_addr[3]);
+ for(int cnt=0; cnt<4; cnt++)
+ {
+ lan2lan_conn.src_ipv6_addr[cnt] = ntohl(lan2lan_conn.src_ipv6_addr[cnt]);
+ }
+ IPACMDBG("After convert src_v6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.src_ipv6_addr[0], lan2lan_conn.src_ipv6_addr[1],
+ lan2lan_conn.src_ipv6_addr[2], lan2lan_conn.src_ipv6_addr[3]);
+
+ memcpy(lan2lan_conn.dst_ipv6_addr, orig_params.dst,
+ sizeof(lan2lan_conn.dst_ipv6_addr));
+ IPACMDBG("Before convert, dst_ipv6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.dst_ipv6_addr[0], lan2lan_conn.dst_ipv6_addr[1],
+ lan2lan_conn.dst_ipv6_addr[2], lan2lan_conn.dst_ipv6_addr[3]);
+ for(int cnt=0; cnt<4; cnt++)
+ {
+ lan2lan_conn.dst_ipv6_addr[cnt] = ntohl(lan2lan_conn.dst_ipv6_addr[cnt]);
+ }
+ IPACMDBG("After convert, dst_ipv6_addr: 0x%08x%08x%08x%08x\n", lan2lan_conn.dst_ipv6_addr[0], lan2lan_conn.dst_ipv6_addr[1],
+ lan2lan_conn.dst_ipv6_addr[2], lan2lan_conn.dst_ipv6_addr[3]);
+
+ if(((IPPROTO_UDP == l4proto) && (NFCT_T_NEW == evt_data->type)) ||
+ ((IPPROTO_TCP == l4proto) &&
+ (nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED))
+ )
+ {
+ p_lan2lan->handle_new_connection(&lan2lan_conn);
+ }
+ else if((IPPROTO_UDP == l4proto && NFCT_T_DESTROY == evt_data->type) ||
+ (IPPROTO_TCP == l4proto &&
+ nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT))
+ {
+ p_lan2lan->handle_del_connection(&lan2lan_conn);
+ }
+
+IGNORE:
+ /* Cleanup item that was allocated during the original CT callback */
+ nfct_destroy(ct);
+ return;
+}
+#endif
+
+void IPACM_ConntrackListener::ProcessCTMessage(void *param)
+{
+ ipacm_ct_evt_data *evt_data = (ipacm_ct_evt_data *)param;
+ u_int8_t l4proto = 0;
+
+#ifdef IPACM_DEBUG
+ char buf[1024];
+ unsigned int out_flags;
+
+ /* Process message and generate ioctl call to kernel thread */
+ out_flags = (NFCT_OF_SHOW_LAYER3 | NFCT_OF_TIME | NFCT_OF_ID);
+ nfct_snprintf(buf, sizeof(buf), evt_data->ct,
+ evt_data->type, NFCT_O_PLAIN, out_flags);
+ IPACMDBG("%s\n", buf);
+ IPACMDBG("\n");
ParseCTMessage(evt_data->ct);
#endif
@@ -505,6 +677,7 @@
uint32_t orig_src_ip, orig_dst_ip;
bool isTempEntry = false;
+ memset(&rule, 0, sizeof(rule));
pConfig = IPACM_Config::GetInstance();
if(pConfig == NULL)
{
@@ -514,6 +687,9 @@
IPACMDBG("Received type:%d with proto:%d\n", type, l4proto);
status = nfct_get_attr_u32(ct, ATTR_STATUS);
+ /* Retrieve Protocol */
+ rule.protocol = nfct_get_attr_u8(ct, ATTR_REPL_L4PROTO);
+
if(IPS_DST_NAT & status)
{
status = IPS_DST_NAT;
@@ -525,7 +701,7 @@
else
{
IPACMDBG("Neither Destination nor Source nat flag Set\n");
- orig_src_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
+ orig_src_ip = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC);
orig_src_ip = ntohl(orig_src_ip);
if(orig_src_ip == 0)
{
@@ -556,21 +732,31 @@
IPACMDBG("Neither orig src ip:0x%x Nor orig Dst IP:0x%x equal to wan ip:0x%x\n",
orig_src_ip, orig_dst_ip, wan_ipaddr);
- if(pConfig != NULL)
- {
- if(pConfig->isPrivateSubnet(orig_src_ip) &&
- (IPS_SRC_NAT_DONE & status))
- {
- IPACMDBG("orig src ip:0x%x match private subnet\n",
- orig_src_ip);
- status = IPS_SRC_NAT;
- }
- else
- {
- return;
- }
- }
+#ifdef CT_OPT
+ if(p_lan2lan == NULL)
+ {
+ IPACMERR("Lan2Lan Instance is null\n");
+ goto IGNORE;
+ }
+ ipacm_event_connection lan2lan_conn = { 0 };
+ lan2lan_conn.iptype = IPA_IP_v4;
+ lan2lan_conn.src_ipv4_addr = orig_src_ip;
+ lan2lan_conn.dst_ipv4_addr = orig_dst_ip;
+
+ if(((IPPROTO_UDP == rule.protocol) && (NFCT_T_NEW == type)) ||
+ ((IPPROTO_TCP == rule.protocol) && (nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_ESTABLISHED)))
+ {
+ p_lan2lan->handle_new_connection(&lan2lan_conn);
+ }
+ else if((IPPROTO_UDP == rule.protocol && NFCT_T_DESTROY == type) ||
+ (IPPROTO_TCP == rule.protocol &&
+ nfct_get_attr_u8(ct, ATTR_TCP_STATE) == TCP_CONNTRACK_FIN_WAIT))
+ {
+ p_lan2lan->handle_del_connection(&lan2lan_conn);
+ }
+#endif
+ return;
}
}
@@ -661,9 +847,6 @@
goto IGNORE;
}
- /* Retrieve Protocol */
- rule.protocol = nfct_get_attr_u8(ct, ATTR_REPL_L4PROTO);
-
if(rule.private_ip != wan_ipaddr)
{
int cnt;
@@ -675,7 +858,7 @@
rule.target_ip == nat_iface_ipv4_addr[cnt])
{
IPACMDBG("matched nat_iface_ipv4_addr entry(%d)\n", cnt);
- IPACM_ConntrackClient::iptodot("ProcessTCPorUDPMsg(): Nat entry match with ip addr",
+ iptodot("ProcessTCPorUDPMsg(): Nat entry match with ip addr",
nat_iface_ipv4_addr[cnt]);
break;
}
@@ -715,11 +898,11 @@
rule.private_port, rule.public_port);
rule.private_port = rule.public_port;
}
-
+
IPACMDBG("Nat Entry with below information will either be added or deleted\n");
- IPACM_ConntrackClient::iptodot("target ip or dst ip", rule.target_ip);
+ iptodot("target ip or dst ip", rule.target_ip);
IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", rule.target_port, rule.target_port);
- IPACM_ConntrackClient::iptodot("private ip or src ip", rule.private_ip);
+ iptodot("private ip or src ip", rule.private_ip);
IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", rule.private_port, rule.private_port);
IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n", rule.public_port, rule.public_port);
IPACMDBG("Protocol: %d, destination nat flag: %d\n", rule.protocol, rule.dst_nat);
@@ -806,9 +989,9 @@
IGNORE:
IPACMDBG("ignoring below Nat Entry\n");
- IPACM_ConntrackClient::iptodot("target ip or dst ip", rule.target_ip);
+ iptodot("target ip or dst ip", rule.target_ip);
IPACMDBG("target port or dst port: 0x%x Decimal:%d\n", rule.target_port, rule.target_port);
- IPACM_ConntrackClient::iptodot("private ip or src ip", rule.private_ip);
+ iptodot("private ip or src ip", rule.private_ip);
IPACMDBG("private port or src port: 0x%x, Decimal:%d\n", rule.private_port, rule.private_port);
IPACMDBG("public port or reply dst port: 0x%x, Decimal:%d\n", rule.public_port, rule.public_port);
IPACMDBG("Protocol: %d, destination nat flag: %d\n", rule.protocol, rule.dst_nat);
diff --git a/ipacm/src/IPACM_Conntrack_NATApp.cpp b/ipacm/src/IPACM_Conntrack_NATApp.cpp
index 3cc2f8a..2424248 100644
--- a/ipacm/src/IPACM_Conntrack_NATApp.cpp
+++ b/ipacm/src/IPACM_Conntrack_NATApp.cpp
@@ -188,8 +188,8 @@
cache[cnt].protocol == rule->protocol)
{
IPACMDBG("Duplicate Rule\n");
- IPACM_ConntrackClient::iptodot("Private IP", rule->private_ip);
- IPACM_ConntrackClient::iptodot("Target IP", rule->target_ip);
+ iptodot("Private IP", rule->private_ip);
+ iptodot("Target IP", rule->target_ip);
IPACMDBG("Private Port: %d\t Target Port: %d\t", rule->private_port, rule->target_port);
IPACMDBG("protocolcol: %d\n", rule->protocol);
return true;
@@ -208,8 +208,8 @@
CHK_TBL_HDL();
IPACMDBG("Received below nat entry for deletion\n");
- IPACM_ConntrackClient::iptodot("Private IP", rule->private_ip);
- IPACM_ConntrackClient::iptodot("Target IP", rule->target_ip);
+ iptodot("Private IP", rule->private_ip);
+ iptodot("Target IP", rule->target_ip);
IPACMDBG("Private Port: %d\t Target Port: %d\t", rule->private_port, rule->target_port);
IPACMDBG("protocolcol: %d\n", rule->protocol);
@@ -257,8 +257,8 @@
CHK_TBL_HDL();
IPACMDBG("Received below nat entry for addition\n");
- IPACM_ConntrackClient::iptodot("Private IP", rule->private_ip);
- IPACM_ConntrackClient::iptodot("Target IP", rule->target_ip);
+ iptodot("Private IP", rule->private_ip);
+ iptodot("Target IP", rule->target_ip);
IPACMDBG("Private Port: %d\t Target Port: %d\t", rule->private_port, rule->target_port);
IPACMDBG("protocolcol: %d\n", rule->protocol);
@@ -356,8 +356,8 @@
{
int ret;
- IPACM_ConntrackClient::iptodot("Private IP:", rule->private_ip);
- IPACM_ConntrackClient::iptodot("Target IP:", rule->target_ip);
+ iptodot("Private IP:", rule->private_ip);
+ iptodot("Target IP:", rule->target_ip);
IPACMDBG("Private Port: %d, Target Port: %d\n", rule->private_port, rule->target_port);
if(!ct_hdl)
@@ -413,8 +413,8 @@
IPACMDBG("dst nat is set\n");
}
- IPACM_ConntrackClient::iptodot("Source IP:", nfct_get_attr_u32(ct, ATTR_IPV4_SRC));
- IPACM_ConntrackClient::iptodot("Destination IP:", nfct_get_attr_u32(ct, ATTR_IPV4_DST));
+ iptodot("Source IP:", nfct_get_attr_u32(ct, ATTR_IPV4_SRC));
+ iptodot("Destination IP:", nfct_get_attr_u32(ct, ATTR_IPV4_DST));
IPACMDBG("Source Port: %d, Destination Port: %d\n",
nfct_get_attr_u16(ct, ATTR_PORT_SRC), nfct_get_attr_u16(ct, ATTR_PORT_DST));
@@ -593,8 +593,8 @@
cache[cnt].enabled = true;
IPACMDBG("On power reset added below rule successfully\n");
- IPACM_ConntrackClient::iptodot("Private IP", nat_rule.private_ip);
- IPACM_ConntrackClient::iptodot("Target IP", nat_rule.target_ip);
+ iptodot("Private IP", nat_rule.private_ip);
+ iptodot("Target IP", nat_rule.target_ip);
IPACMDBG("Private Port:%d \t Target Port: %d\t", nat_rule.private_port, nat_rule.target_port);
IPACMDBG("Public Port:%d\n", nat_rule.public_port);
IPACMDBG("protocol: %d\n", nat_rule.protocol);
@@ -634,8 +634,8 @@
int cnt;
IPACMDBG("Received below nat entry\n");
- IPACM_ConntrackClient::iptodot("Private IP", new_entry->private_ip);
- IPACM_ConntrackClient::iptodot("Target IP", new_entry->target_ip);
+ iptodot("Private IP", new_entry->private_ip);
+ iptodot("Target IP", new_entry->target_ip);
IPACMDBG("Private Port: %d\t Target Port: %d\t", new_entry->private_port, new_entry->target_port);
IPACMDBG("protocolcol: %d\n", new_entry->protocol);
@@ -659,8 +659,8 @@
int cnt;
IPACMDBG("Received below nat entry\n");
- IPACM_ConntrackClient::iptodot("Private IP", entry->private_ip);
- IPACM_ConntrackClient::iptodot("Target IP", entry->target_ip);
+ iptodot("Private IP", entry->private_ip);
+ iptodot("Target IP", entry->target_ip);
IPACMDBG("Private Port: %d\t Target Port: %d\t", entry->private_port, entry->target_port);
IPACMDBG("protocolcol: %d\n", entry->protocol);
@@ -688,7 +688,7 @@
int ret;
IPACMDBG("Received below with isAdd:%d\n", isAdd);
- IPACM_ConntrackClient::iptodot("IP Address:", ip_addr);
+ iptodot("IP Address:", ip_addr);
for(cnt=0; cnt<MAX_TEMP_ENTRIES; cnt++)
{
diff --git a/ipacm/src/IPACM_Lan.cpp b/ipacm/src/IPACM_Lan.cpp
index 5063e36..008a185 100644
--- a/ipacm/src/IPACM_Lan.cpp
+++ b/ipacm/src/IPACM_Lan.cpp
@@ -93,6 +93,9 @@
is_active = true;
+ memset(tcp_ctl_flt_rule_hdl_v4, 0, NUM_TCP_CTL_FLT_RULE*sizeof(uint32_t));
+ memset(tcp_ctl_flt_rule_hdl_v6, 0, NUM_TCP_CTL_FLT_RULE*sizeof(uint32_t));
+
return;
}
@@ -382,7 +385,13 @@
return IPACM_FAILURE;
}
- flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+#ifdef CT_OPT
+ flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR
+ + NUM_TCP_CTL_FLT_RULE + IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+#else
+ flt_rule_count_v4 = IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR
+ IPACM_Iface::ipacmcfg->ipa_num_private_subnet;
+#endif
if(is_sta_mode == false)
{
@@ -477,8 +486,11 @@
dft_rt_rule_hdl[0] = rt_rule_entry->rt_rule_hdl;
IPACMDBG("ipv4 iface rt-rule hdl1=0x%x\n", dft_rt_rule_hdl[0]);
/* initial multicast/broadcast/fragment filter rule */
- init_fl_rule(data->iptype);
+#ifdef CT_OPT
+ install_tcp_ctl_flt_rule(IPA_IP_v4);
+#endif
add_dummy_lan2lan_flt_rule(data->iptype);
+ init_fl_rule(data->iptype);
}
else
{
@@ -563,9 +575,12 @@
if (num_dft_rt_v6 == 0)
{
+#ifdef CT_OPT
+ install_tcp_ctl_flt_rule(IPA_IP_v6);
+#endif
+ add_dummy_lan2lan_flt_rule(data->iptype);
/* initial multicast/broadcast/fragment filter rule */
init_fl_rule(data->iptype);
- add_dummy_lan2lan_flt_rule(data->iptype);
}
num_dft_rt_v6++;
}
@@ -1605,15 +1620,20 @@
/* delete default filter rules */
if (ip_type != IPA_IP_v6 && rx_prop != NULL)
{
- if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl,
- IPA_IP_v4,
- IPV4_DEFAULT_FILTERTING_RULES) == false)
+ if (m_filtering.DeleteFilteringHdls(dft_v4fl_rule_hdl, IPA_IP_v4, IPV4_DEFAULT_FILTERTING_RULES) == false)
{
- IPACMERR("Error Adding Filtering Rule, aborting...\n");
+ IPACMERR("Error deleting default filtering Rule, aborting...\n");
res = IPACM_FAILURE;
goto fail;
}
-
+#ifdef CT_OPT
+ if (m_filtering.DeleteFilteringHdls(tcp_ctl_flt_rule_hdl_v4, IPA_IP_v4, NUM_TCP_CTL_FLT_RULE) == false)
+ {
+ IPACMERR("Error deleting default filtering Rule, aborting...\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+#endif
for(i=0; i<MAX_OFFLOAD_PAIR; i++)
{
if(m_filtering.DeleteFilteringHdls(&(lan2lan_flt_rule_hdl_v4[i].rule_hdl), IPA_IP_v4, 1) == false)
@@ -1626,10 +1646,7 @@
IPACMDBG("Deleted lan2lan IPv4 flt rules.\n");
/* free private-subnet ipv4 filter rules */
- if (m_filtering.DeleteFilteringHdls(
- private_fl_rule_hdl,
- IPA_IP_v4,
- IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false)
+ if (m_filtering.DeleteFilteringHdls(private_fl_rule_hdl, IPA_IP_v4, IPACM_Iface::ipacmcfg->ipa_num_private_subnet) == false)
{
IPACMERR("Error Deleting RuleTable(1) to Filtering, aborting...\n");
res = IPACM_FAILURE;
@@ -1649,7 +1666,14 @@
res = IPACM_FAILURE;
goto fail;
}
-
+#ifdef CT_OPT
+ if (m_filtering.DeleteFilteringHdls(tcp_ctl_flt_rule_hdl_v6, IPA_IP_v6, NUM_TCP_CTL_FLT_RULE) == false)
+ {
+ IPACMERR("Error deleting default filtering Rule, aborting...\n");
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+#endif
for(i=0; i<MAX_OFFLOAD_PAIR; i++)
{
if(m_filtering.DeleteFilteringHdls(&(lan2lan_flt_rule_hdl_v6[i].rule_hdl), IPA_IP_v6, 1) == false)
@@ -1866,7 +1890,11 @@
return IPACM_FAILURE;
}
+#ifdef CT_OPT
+ flt_rule_count_v6 = IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR;
+#else
flt_rule_count_v6 = IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR;
+#endif
if(is_sta_mode == false)
{
@@ -2984,3 +3012,103 @@
} /* end of for loop */
return;
}
+
+void IPACM_Lan::install_tcp_ctl_flt_rule(ipa_ip_type iptype)
+{
+ if (rx_prop == NULL)
+ {
+ IPACMDBG("No rx properties registered for iface %s\n", dev_name);
+ return;
+ }
+
+ int len, i;
+ struct ipa_flt_rule_add flt_rule;
+ ipa_ioc_add_flt_rule* pFilteringTable;
+
+ len = sizeof(struct ipa_ioc_add_flt_rule) + NUM_TCP_CTL_FLT_RULE * sizeof(struct ipa_flt_rule_add);
+
+ pFilteringTable = (struct ipa_ioc_add_flt_rule *)malloc(len);
+ if (pFilteringTable == NULL)
+ {
+ IPACMERR("Error allocate flt table memory...\n");
+ return;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = iptype;
+ pFilteringTable->ep = rx_prop->rx[0].src_pipe;
+ pFilteringTable->global = false;
+ pFilteringTable->num_rules = NUM_TCP_CTL_FLT_RULE;
+
+ memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_add));
+
+ flt_rule.at_rear = true;
+ flt_rule.flt_rule_hdl = -1;
+ flt_rule.status = -1;
+
+ flt_rule.rule.retain_hdr = 1;
+ flt_rule.rule.to_uc = 0;
+ flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
+ flt_rule.rule.eq_attrib_type = 1;
+
+ flt_rule.rule.eq_attrib.rule_eq_bitmap = 0;
+
+ flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<14);
+ flt_rule.rule.eq_attrib.metadata_meq32_present = 1;
+ flt_rule.rule.eq_attrib.metadata_meq32.offset = 0;
+ flt_rule.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data;
+ flt_rule.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask;
+
+ flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<1);
+ flt_rule.rule.eq_attrib.protocol_eq_present = 1;
+ flt_rule.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP;
+
+ flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<8);
+ flt_rule.rule.eq_attrib.num_ihl_offset_meq_32 = 1;
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12;
+
+ /* add TCP FIN rule*/
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT);
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT);
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_add));
+
+ /* add TCP SYN rule*/
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_SYN_SHIFT);
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_SYN_SHIFT);
+ memcpy(&(pFilteringTable->rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_add));
+
+ /* add TCP RST rule*/
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_RST_SHIFT);
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT);
+ memcpy(&(pFilteringTable->rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_add));
+
+ if (false == m_filtering.AddFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Error adding tcp control flt rule\n");
+ goto fail;
+ }
+ else
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++)
+ {
+ flt_rule_count_v4++;
+ tcp_ctl_flt_rule_hdl_v4[i] = pFilteringTable->rules[i].flt_rule_hdl;
+ }
+ }
+ else
+ {
+ for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++)
+ {
+ flt_rule_count_v6++;
+ tcp_ctl_flt_rule_hdl_v6[i] = pFilteringTable->rules[i].flt_rule_hdl;
+ }
+ }
+ }
+
+fail:
+ free(pFilteringTable);
+ return;
+}
diff --git a/ipacm/src/IPACM_LanToLan.cpp b/ipacm/src/IPACM_LanToLan.cpp
index ed9a671..562c233 100644
--- a/ipacm/src/IPACM_LanToLan.cpp
+++ b/ipacm/src/IPACM_LanToLan.cpp
@@ -43,6 +43,8 @@
#include "IPACM_LanToLan.h"
#include "IPACM_Wlan.h"
+IPACM_LanToLan* IPACM_LanToLan::p_instance = NULL;
+
IPACM_LanToLan::IPACM_LanToLan()
{
num_offload_pair_v4_ = 0;
@@ -50,6 +52,8 @@
client_info_v4_.reserve(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT);
client_info_v6_.reserve(3*(IPA_LAN_TO_LAN_MAX_WLAN_CLIENT + IPA_LAN_TO_LAN_MAX_USB_CLIENT));
+ p_instance = this;
+
IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_ACTIVE, this);
IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_INACTIVE, this);
IPACM_EvtDispatcher::registr(IPA_LAN_CLIENT_DISCONNECT, this);
@@ -115,7 +119,7 @@
{
IPACMDBG("Get IPA_LAN_TO_LAN_NEW_CONNECTION event.\n");
ipacm_event_connection* data = (ipacm_event_connection*)param;
- handle_new_connection(data);
+ handle_new_lan2lan_connection(data);
break;
}
@@ -123,7 +127,7 @@
{
IPACMDBG("Get IPA_LAN_TO_LAN_DEL_CONNECTION event.\n");
ipacm_event_connection* data = (ipacm_event_connection*)param;
- handle_del_connection(data);
+ handle_del_lan2lan_connection(data);
break;
}
case IPA_LAN_CLIENT_POWER_SAVE:
@@ -205,7 +209,7 @@
client_ptr->is_powersave = false;
client_ptr->p_iface = data->p_iface;
- generate_new_connection(data->iptype, client_ptr); //code review: remember of remove this once listening to real connection evt
+ generate_new_connection(data->iptype, client_ptr);
}
else //the client is found
{
@@ -700,20 +704,9 @@
return;
}
-void IPACM_LanToLan::handle_new_connection(ipacm_event_connection* data)
+void IPACM_LanToLan::handle_new_lan2lan_connection(ipacm_event_connection* data)
{
- if(data == NULL)
- {
- IPACMERR("No connection info is found.\n");
- return;
- }
- if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6)
- {
- IPACMERR("IP type is not expected: %d.\n", data->iptype);
- return;
- }
-
- IPACMDBG("New connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", data->iptype, data->src_ipv4_addr, data->dst_ipv4_addr);
+ IPACMDBG("New lan2lan connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", data->iptype, data->src_ipv4_addr, data->dst_ipv4_addr);
IPACMDBG("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", data->src_ipv6_addr[0], data->src_ipv6_addr[1], data->src_ipv6_addr[2],
data->src_ipv6_addr[3], data->dst_ipv6_addr[0], data->dst_ipv6_addr[1], data->dst_ipv6_addr[2], data->dst_ipv6_addr[3]);
@@ -834,20 +827,9 @@
return ret;
}
-void IPACM_LanToLan::handle_del_connection(ipacm_event_connection* data)
+void IPACM_LanToLan::handle_del_lan2lan_connection(ipacm_event_connection* data)
{
- if(data == NULL)
- {
- IPACMERR("No connection info is found.\n");
- return;
- }
- if(data->iptype != IPA_IP_v4 && data->iptype != IPA_IP_v6)
- {
- IPACMERR("IP type is not expected: %d.\n", data->iptype)
- return;
- }
-
- IPACMDBG("Del connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", data->iptype, data->src_ipv4_addr, data->dst_ipv4_addr);
+ IPACMDBG("Del lan2lan connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", data->iptype, data->src_ipv4_addr, data->dst_ipv4_addr);
IPACMDBG("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", data->src_ipv6_addr[0], data->src_ipv6_addr[1], data->src_ipv6_addr[2],
data->src_ipv6_addr[3], data->dst_ipv6_addr[0], data->dst_ipv6_addr[1], data->dst_ipv6_addr[2], data->dst_ipv6_addr[3]);
@@ -956,7 +938,7 @@
IPACMDBG("Find dst client entry in src peer list, connection count: %d\n", it->num_connection);
if(it->num_connection == 0)
{
- IPACMDBG("Need to remove dst entry in src peer list");
+ IPACMDBG("Need to remove dst entry in src peer list.\n");
ret = true;
}
break;
@@ -976,7 +958,7 @@
IPACMDBG("Find src client entry in dst peer list, connection count: %d\n", it->num_connection);
if(it->num_connection == 0)
{
- IPACMDBG("Need to remove src entry in dst peer list");
+ IPACMDBG("Need to remove src entry in dst peer list.\n");
ret = true;
}
break;
@@ -1042,6 +1024,7 @@
void IPACM_LanToLan::generate_new_connection(ipa_ip_type iptype, client_info* client)
{
+#ifndef CT_OPT
if(client == NULL)
{
IPACMERR("Client is NULL.\n");
@@ -1121,6 +1104,7 @@
IPACMERR("IP type is not expected.\n");
}
IPACMDBG("Generate %d new connection events in total.\n", num);
+#endif
return;
}
@@ -1284,3 +1268,129 @@
return IPACM_SUCCESS;
}
+void IPACM_LanToLan::handle_new_connection(ipacm_event_connection* new_conn)
+{
+#ifdef CT_OPT
+ if(new_conn == NULL)
+ {
+ IPACMERR("No connection info is found.\n");
+ return;
+ }
+ if(new_conn->iptype != IPA_IP_v4 && new_conn->iptype != IPA_IP_v6)
+ {
+ IPACMERR("IP type is not expected: %d.\n", new_conn->iptype);
+ return;
+ }
+
+ IPACMDBG("New connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", new_conn->iptype, new_conn->src_ipv4_addr, new_conn->dst_ipv4_addr);
+ IPACMDBG("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", new_conn->src_ipv6_addr[0], new_conn->src_ipv6_addr[1], new_conn->src_ipv6_addr[2],
+ new_conn->src_ipv6_addr[3], new_conn->dst_ipv6_addr[0], new_conn->dst_ipv6_addr[1], new_conn->dst_ipv6_addr[2], new_conn->dst_ipv6_addr[3]);
+
+ if(is_lan2lan_connection(new_conn) == false)
+ {
+ IPACMDBG("The connection is not lan2lan connection.\n");
+ return;
+ }
+
+ ipacm_cmd_q_data evt;
+ ipacm_event_connection* conn;
+
+ conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection));
+ if(conn == NULL)
+ {
+ IPACMERR("Failed to allocate memory for new_connection event.\n");
+ return;
+ }
+ memcpy(conn, new_conn, sizeof(ipacm_event_connection));
+
+ memset(&evt, 0, sizeof(evt));
+ evt.event = IPA_LAN_TO_LAN_NEW_CONNECTION;
+ evt.evt_data = (void*)conn;
+ IPACM_EvtDispatcher::PostEvt(&evt);
+#endif
+ return;
+}
+
+void IPACM_LanToLan::handle_del_connection(ipacm_event_connection* new_conn)
+{
+#ifdef CT_OPT
+ if(new_conn == NULL)
+ {
+ IPACMERR("No connection info is found.\n");
+ return;
+ }
+ if(new_conn->iptype != IPA_IP_v4 && new_conn->iptype != IPA_IP_v6)
+ {
+ IPACMERR("IP type is not expected: %d.\n", new_conn->iptype);
+ return;
+ }
+
+ IPACMDBG("Del connection info: IP type: %d, src_v4_addr: 0x%08x, dst_v4_addr: 0x%08x\n", new_conn->iptype, new_conn->src_ipv4_addr, new_conn->dst_ipv4_addr);
+ IPACMDBG("src_v6_addr: 0x%08x%08x%08x%08x, dst_v6_addr: 0x%08x%08x%08x%08x", new_conn->src_ipv6_addr[0], new_conn->src_ipv6_addr[1], new_conn->src_ipv6_addr[2],
+ new_conn->src_ipv6_addr[3], new_conn->dst_ipv6_addr[0], new_conn->dst_ipv6_addr[1], new_conn->dst_ipv6_addr[2], new_conn->dst_ipv6_addr[3]);
+
+ if(is_lan2lan_connection(new_conn) == false)
+ {
+ IPACMDBG("The connection is not lan2lan connection.\n");
+ return;
+ }
+
+ ipacm_cmd_q_data evt;
+ ipacm_event_connection* conn;
+
+ conn = (ipacm_event_connection*)malloc(sizeof(ipacm_event_connection));
+ if(conn == NULL)
+ {
+ IPACMERR("Failed to allocate memory for del_connection event.\n");
+ return;
+ }
+ memcpy(conn, new_conn, sizeof(ipacm_event_connection));
+
+ memset(&evt, 0, sizeof(evt));
+ evt.event = IPA_LAN_TO_LAN_DEL_CONNECTION;
+ evt.evt_data = (void*)conn;
+ IPACM_EvtDispatcher::PostEvt(&evt);
+#endif
+ return;
+}
+
+bool IPACM_LanToLan::is_lan2lan_connection(ipacm_event_connection* data)
+{
+ if(data->iptype == IPA_IP_v4)
+ {
+ if(client_info_v4_.count(data->src_ipv4_addr) == 0 || client_info_v4_.count(data->dst_ipv4_addr) == 0)
+ {
+ IPACMDBG("Either source or destination is not in client table\n");
+ return false;
+ }
+
+ ipacm_iface_type src_type, dst_type;
+ src_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v4_[data->src_ipv4_addr].p_iface->ipa_if_num].if_cat;
+ dst_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v4_[data->dst_ipv4_addr].p_iface->ipa_if_num].if_cat;
+
+ return (src_type != dst_type);
+ }
+ else
+ {
+ uint64_t src_v6_addr, dst_v6_addr;
+ memcpy(&src_v6_addr, &(data->src_ipv6_addr[2]), sizeof(uint64_t));
+ memcpy(&dst_v6_addr, &(data->dst_ipv6_addr[2]), sizeof(uint64_t));
+
+ if(client_info_v6_.count(src_v6_addr) == 0 || client_info_v6_.count(dst_v6_addr) == 0)
+ {
+ IPACMDBG("Either source or destination is not in client table\n");
+ return false;
+ }
+
+ ipacm_iface_type src_type, dst_type;
+ src_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v6_[src_v6_addr].p_iface->ipa_if_num].if_cat;
+ dst_type = IPACM_Iface::ipacmcfg->iface_table[client_info_v6_[dst_v6_addr].p_iface->ipa_if_num].if_cat;
+
+ return (src_type != dst_type);
+ }
+}
+
+IPACM_LanToLan* IPACM_LanToLan::getLan2LanInstance()
+{
+ return p_instance;
+}
diff --git a/ipacm/src/IPACM_Main.cpp b/ipacm/src/IPACM_Main.cpp
index e942a1a..cab2963 100644
--- a/ipacm/src/IPACM_Main.cpp
+++ b/ipacm/src/IPACM_Main.cpp
@@ -67,8 +67,9 @@
#include "IPACM_Log.h"
#include "IPACM_ConntrackListener.h"
-
+#include "IPACM_ConntrackClient.h"
#include "IPACM_LanToLan.h"
+#include "IPACM_Netlink.h"
const char *ipacm_event_name[] = {
__stringify(IPA_LINK_UP_EVENT),
@@ -550,9 +551,12 @@
/* check if ipacm is already running or not */
ipa_is_ipacm_running();
+ IPACMDBG("In main()\n");
IPACM_Neighbor *neigh = new IPACM_Neighbor();
IPACM_IfaceManager *ifacemgr = new IPACM_IfaceManager();
IPACM_LanToLan* lan2lan = new IPACM_LanToLan();
+ IPACM_ConntrackClient *cc = IPACM_ConntrackClient::GetInstance();
+ CtList = new IPACM_ConntrackListener();
IPACMDBG("Staring IPA main\n");
IPACMDBG("ipa_cmdq_successful\n");
diff --git a/ipacm/src/IPACM_Wlan.cpp b/ipacm/src/IPACM_Wlan.cpp
index 35ea0eb..0d8b916 100644
--- a/ipacm/src/IPACM_Wlan.cpp
+++ b/ipacm/src/IPACM_Wlan.cpp
@@ -531,8 +531,13 @@
IPACMERR("Dummy ipv4 flt rule has not been installed.\n");
return IPACM_FAILURE;
}
-
- offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#ifndef CT_OPT
+ offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet)
+ + MAX_OFFLOAD_PAIR;
+#else
+ offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet)
+ + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR;
+#endif
len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPV4_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_mdfy));
pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len);
if (!pFilteringTable)
@@ -608,8 +613,13 @@
IPACMERR("Dummy ipv6 flt rule has not been installed.\n");
return IPACM_FAILURE;
}
-
- offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR);
+#ifndef CT_OPT
+ offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR)
+ + MAX_OFFLOAD_PAIR;
+#else
+ offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR)
+ + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR;
+#endif
len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPV6_DEFAULT_FILTERTING_RULES * sizeof(struct ipa_flt_rule_mdfy));
pFilteringTable = (struct ipa_ioc_mdfy_flt_rule *)calloc(1, len);
if (!pFilteringTable)
@@ -715,10 +725,16 @@
return IPACM_FAILURE;
}
+#ifndef CT_OPT
offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#else
+ offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet)
+ + NUM_TCP_CTL_FLT_RULE;
+#endif
+
for (int i = 0; i < MAX_OFFLOAD_PAIR; i++)
{
- lan2lan_flt_rule_hdl_v4[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+IPV4_DEFAULT_FILTERTING_RULES+i];
+ lan2lan_flt_rule_hdl_v4[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i];
lan2lan_flt_rule_hdl_v4[i].valid = false;
IPACMDBG("Lan2lan v4 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v4[i].rule_hdl);
}
@@ -731,10 +747,16 @@
return IPACM_FAILURE;
}
+#ifndef CT_OPT
offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR);
+#else
+ offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR)
+ + NUM_TCP_CTL_FLT_RULE;
+#endif
+
for (int i = 0; i < MAX_OFFLOAD_PAIR; i++)
{
- lan2lan_flt_rule_hdl_v6[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+IPV6_DEFAULT_FILTERTING_RULES+i];
+ lan2lan_flt_rule_hdl_v6[i].rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+i];
lan2lan_flt_rule_hdl_v6[i].valid = false;
IPACMDBG("Lan2lan v6 flt rule %d hdl:0x%x\n", i, lan2lan_flt_rule_hdl_v6[i].rule_hdl);
}
@@ -769,7 +791,13 @@
return IPACM_FAILURE;
}
- offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#ifndef CT_OPT
+ offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet)
+ + IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR;
+#else
+ offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet)
+ + IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR;
+#endif
len = sizeof(struct ipa_ioc_mdfy_flt_rule) + (IPACM_Iface::ipacmcfg->ipa_num_private_subnet) * sizeof(struct ipa_flt_rule_mdfy);
pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
@@ -807,7 +835,7 @@
for (i = 0; i < (IPACM_Iface::ipacmcfg->ipa_num_private_subnet); i++)
{
- flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR+i];
+ flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+i];
flt_rule.rule.attrib.u.v4.dst_addr_mask = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_mask;
flt_rule.rule.attrib.u.v4.dst_addr = IPACM_Iface::ipacmcfg->private_subnet_table[i].subnet_addr;
memcpy(&(pFilteringTable->rules[i]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
@@ -917,11 +945,19 @@
if(iptype == IPA_IP_v4)
{
+#ifndef CT_OPT
offset = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#else
+ offset = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+#endif
}
else
{
+#ifndef CT_OPT
offset = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR);
+#else
+ offset = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR);
+#endif
}
for(cnt=0; cnt<prop->num_ext_props; cnt++)
@@ -1705,7 +1741,7 @@
goto fail;
}
- /* Delete v6 filtering rules */
+ /* Delete v4 filtering rules */
if (ip_type != IPA_IP_v6 && rx_prop != NULL)
{
IPACMDBG("Delete default v4 filter rules\n");
@@ -1719,7 +1755,18 @@
goto fail;
}
}
-
+#ifdef CT_OPT
+ IPACMDBG("Delete tcp control flt rules.\n");
+ /* Delete tcp control flt rules */
+ for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v4, tcp_ctl_flt_rule_hdl_v4[i]) == IPACM_FAILURE)
+ {
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+#endif
IPACMDBG("Delete lan2lan v4 flt rules.\n");
/* delete lan2lan ipv4 flt rules */
for(i=0; i<MAX_OFFLOAD_PAIR; i++)
@@ -1745,7 +1792,7 @@
}
}
- /* Delete v4 filtering rules */
+ /* Delete v6 filtering rules */
if (ip_type != IPA_IP_v4 && rx_prop != NULL)
{
IPACMDBG("Delete default %d v6 filter rules\n", IPV6_DEFAULT_FILTERTING_RULES);
@@ -1758,7 +1805,18 @@
goto fail;
}
}
-
+#ifdef CT_OPT
+ IPACMDBG("Delete tcp control flt rules.\n");
+ /* Delete tcp control flt rules */
+ for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++)
+ {
+ if(reset_to_dummy_flt_rule(IPA_IP_v6, tcp_ctl_flt_rule_hdl_v6[i]) == IPACM_FAILURE)
+ {
+ res = IPACM_FAILURE;
+ goto fail;
+ }
+ }
+#endif
IPACMDBG("Delete lan2lan v6 filter rules\n");
/* delete lan2lan ipv6 filter rules */
for(i=0; i<MAX_OFFLOAD_PAIR; i++)
@@ -2251,10 +2309,13 @@
IPACMERR("Either v4 or v6 dummy filtering rule handle is not empty.\n");
return;
}
-
+#ifndef CT_OPT
num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR);
-
+#else
+ num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+ num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR);
+#endif
IPACM_Wlan::dummy_flt_rule_hdl_v4 = (uint32_t*)malloc(num_v4_dummy_rule * sizeof(uint32_t));
if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL)
{
@@ -2429,9 +2490,13 @@
IPACMERR("Either v4 or v6 dummy flt rule is empty.\n");
return;
}
-
+#ifndef CT_OPT
num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + MAX_OFFLOAD_PAIR);
+#else
+ num_v4_dummy_rule = 2*(IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+ num_v6_dummy_rule = 2*(IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR);
+#endif
if(m_filtering.DeleteFilteringHdls(IPACM_Wlan::dummy_flt_rule_hdl_v4, IPA_IP_v4, num_v4_dummy_rule) == false)
{
IPACMERR("Failed to delete ipv4 dummy flt rules.\n");
@@ -2451,3 +2516,137 @@
return;
}
+void IPACM_Wlan::install_tcp_ctl_flt_rule(ipa_ip_type iptype)
+{
+ if (rx_prop == NULL)
+ {
+ IPACMDBG("No rx properties registered for iface %s\n", dev_name);
+ return;
+ }
+
+ int i, len, res = IPACM_SUCCESS, offset;
+ struct ipa_flt_rule_mdfy flt_rule;
+ struct ipa_ioc_mdfy_flt_rule* pFilteringTable;
+
+ if (iptype == IPA_IP_v4)
+ {
+ if(IPACM_Wlan::dummy_flt_rule_hdl_v4 == NULL)
+ {
+ IPACMERR("Dummy ipv4 flt rule has not been installed.\n");
+ return;
+ }
+ offset = wlan_ap_index * (IPV4_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR + IPACM_Iface::ipacmcfg->ipa_num_private_subnet);
+ }
+ else
+ {
+ if(IPACM_Wlan::dummy_flt_rule_hdl_v6 == NULL)
+ {
+ IPACMERR("Dummy ipv6 flt rule has not been installed.\n");
+ return;
+ }
+ offset = wlan_ap_index * (IPV6_DEFAULT_FILTERTING_RULES + NUM_TCP_CTL_FLT_RULE + MAX_OFFLOAD_PAIR);
+ }
+
+ len = sizeof(struct ipa_ioc_mdfy_flt_rule) + NUM_TCP_CTL_FLT_RULE * sizeof(struct ipa_flt_rule_mdfy);
+ pFilteringTable = (struct ipa_ioc_mdfy_flt_rule*)malloc(len);
+ if (!pFilteringTable)
+ {
+ IPACMERR("Failed to allocate ipa_ioc_mdfy_flt_rule memory...\n");
+ return;
+ }
+ memset(pFilteringTable, 0, len);
+
+ pFilteringTable->commit = 1;
+ pFilteringTable->ip = iptype;
+ pFilteringTable->num_rules = NUM_TCP_CTL_FLT_RULE;
+
+ memset(&flt_rule, 0, sizeof(struct ipa_flt_rule_mdfy));
+ flt_rule.status = -1;
+
+ flt_rule.rule.retain_hdr = 1;
+ flt_rule.rule.to_uc = 0;
+ flt_rule.rule.action = IPA_PASS_TO_EXCEPTION;
+ flt_rule.rule.eq_attrib_type = 1;
+
+ flt_rule.rule.eq_attrib.rule_eq_bitmap = 0;
+
+ flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<14);
+ flt_rule.rule.eq_attrib.metadata_meq32_present = 1;
+ flt_rule.rule.eq_attrib.metadata_meq32.offset = 0;
+ flt_rule.rule.eq_attrib.metadata_meq32.value = rx_prop->rx[0].attrib.meta_data;
+ flt_rule.rule.eq_attrib.metadata_meq32.mask = rx_prop->rx[0].attrib.meta_data_mask;
+
+ flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<1);
+ flt_rule.rule.eq_attrib.protocol_eq_present = 1;
+ flt_rule.rule.eq_attrib.protocol_eq = IPACM_FIREWALL_IPPROTO_TCP;
+
+ /* add TCP FIN rule*/
+ flt_rule.rule.eq_attrib.rule_eq_bitmap |= (1<<8);
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].offset = 12;
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_FIN_SHIFT);
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_FIN_SHIFT);
+ flt_rule.rule.eq_attrib.num_ihl_offset_meq_32 = 1;
+ if(iptype == IPA_IP_v4)
+ {
+ flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset];
+ }
+ else
+ {
+ flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset];
+ }
+ memcpy(&(pFilteringTable->rules[0]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
+
+ /* add TCP SYN rule*/
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_SYN_SHIFT);
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_SYN_SHIFT);
+ if(iptype == IPA_IP_v4)
+ {
+ flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+1];
+ }
+ else
+ {
+ flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+1];
+ }
+ memcpy(&(pFilteringTable->rules[1]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
+
+ /* add TCP RST rule*/
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].value = (((uint32_t)1)<<TCP_RST_SHIFT);
+ flt_rule.rule.eq_attrib.ihl_offset_meq_32[0].mask = (((uint32_t)1)<<TCP_RST_SHIFT);
+ if(iptype == IPA_IP_v4)
+ {
+ flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v4[offset+2];
+ }
+ else
+ {
+ flt_rule.rule_hdl = IPACM_Wlan::dummy_flt_rule_hdl_v6[offset+2];
+ }
+ memcpy(&(pFilteringTable->rules[2]), &flt_rule, sizeof(struct ipa_flt_rule_mdfy));
+
+ if (false == m_filtering.ModifyFilteringRule(pFilteringTable))
+ {
+ IPACMERR("Failed to modify tcp control filtering rules.\n");
+ goto fail;
+ }
+ else
+ {
+ if(iptype == IPA_IP_v4)
+ {
+ for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++)
+ {
+ tcp_ctl_flt_rule_hdl_v4[i] = pFilteringTable->rules[i].rule_hdl;
+ }
+ }
+ else
+ {
+ for(i=0; i<NUM_TCP_CTL_FLT_RULE; i++)
+ {
+ tcp_ctl_flt_rule_hdl_v6[i] = pFilteringTable->rules[i].rule_hdl;
+ }
+ }
+ }
+
+fail:
+ free(pFilteringTable);
+ return;
+}
+
diff --git a/ipacm/src/Makefile.am b/ipacm/src/Makefile.am
index 82cc3dc..254a569 100644
--- a/ipacm/src/Makefile.am
+++ b/ipacm/src/Makefile.am
@@ -2,7 +2,7 @@
-I$(top_srcdir)/ipanat/inc \
${LIBXML_CFLAGS}
AM_CPPFLAGS += -Wall -Wundef -Wno-trigraphs
-AM_CPPFLAGS += -DDEBUG -g
+AM_CPPFLAGS += -DDEBUG -g -DCT_OPT
ipacm_SOURCES = IPACM_Main.cpp \
IPACM_Conntrack_NATApp.cpp\