secgateway/Platform/modules/conntrack_api/api/conntrack_api.c

569 lines
16 KiB
C
Raw Normal View History

2019-06-11 03:21:35 +00:00
#include "conntrack_api.h"
/************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ct<EFBFBD><EFBFBD>չ<EFBFBD>ֶ<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD>16λ<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:sk_buff, value(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ֵ), type(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>־
************************************************************/
int cmhi_set_conntrack_u16(const struct sk_buff *skb, uint16_t value, cmhi_ext_type type)
{
enum ip_conntrack_info ctinfo = {0};
struct nf_conn *ct = NULL;
if(!skb){
printk(KERN_ERR"[CT_API]set_conntrack_u16: skb is null\n");
return CMHI_EXT_ERR;
}
ct = nf_ct_get(skb, &ctinfo);
if(!ct){
printk(KERN_ERR"[CT_API]set-conntrak_u16: ct is not existed or ct is untracked\n");
return CMHI_EXT_ERR;
}
switch (type)
{
case USER_VERSION:
ct->cmhi.user_version = value;
break;
case APP_ID:
ct->cmhi.app_id = value;
break;
default: {
printk(KERN_INFO"[CT_API]set-conntrak_u16: value is not u16\n");
return CMHI_EXT_ERR;
}
}
return CMHI_EXT_OK;
}
/***********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ct<EFBFBD><EFBFBD>չ<EFBFBD>ֶ<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD>32λ<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:sk_buff, value(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ֵ), type(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>־
***********************************************************/
int cmhi_set_conntrack_u32(const struct sk_buff *skb, uint32_t value, cmhi_ext_type type)
{
enum ip_conntrack_info ctinfo = {0};
struct nf_conn *ct = NULL;
if(!skb){
printk(KERN_ERR"[CT_API]set-conntrack_u32: skb is null\n");
return CMHI_EXT_ERR;
}
ct = nf_ct_get(skb, &ctinfo);
if(!ct){
printk(KERN_ERR"[CT_API]set-conntrak_u32: ct is not existed or ct is untracked\n");
return CMHI_EXT_ERR;
}
switch (type)
{
case USER_ID:
ct->cmhi.user_id = value;
break;
case NODE_INDEX:
ct->cmhi.node_index = value;
break;
case POLICY_VERSION:
ct->cmhi.policy_version = value;
break;
case ACTION:
ct->cmhi.action = value;
break;
default: {
printk(KERN_INFO"[CT_API]set-conntrak_u32: value is not u32\n");
return CMHI_EXT_ERR;
}
}
return CMHI_EXT_OK;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD><EFBFBD>ձ<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ct<EFBFBD><EFBFBD>չ<EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD>action<EFBFBD>ֶ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:sk_buff, abit(<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õı<EFBFBD><EFBFBD><EFBFBD>λ)
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>־
**********************************************************/
int cmhi_set_conntrack_action_by_bit(const struct sk_buff *skb, cmhi_ext_action_bit abit)
{
enum ip_conntrack_info ctinfo = {0};
struct nf_conn *ct = NULL;
if(!skb){
printk(KERN_ERR"[CT_API]set-conntrack_action_by_bit: skb is null\n");
return CMHI_EXT_ERR;
}
ct = nf_ct_get(skb, &ctinfo);
if(!ct){
printk(KERN_ERR"[CT_API]set-conntrak_action_by_bit: ct is not existed or ct is untracked\n");
return CMHI_EXT_ERR;
}
switch (abit)
{
case CMHI_EXT_PASS:
case CMHI_EXT_GOTO_DPI:
ct->cmhi.action |= abit;
break;
default: {
printk(KERN_INFO"[CT_API]set-conntrak_action_by_bit: wrong action bit\n");
return CMHI_EXT_ERR;
}
}
return CMHI_EXT_OK;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD>ȡct<EFBFBD><EFBFBD>չ<EFBFBD>ֶ<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD>16λ<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:sk_buff, value(<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ֶε<EFBFBD>ָ<EFBFBD><EFBFBD>), type(<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ֶε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ֶ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: <EFBFBD><EFBFBD>ȡ<EFBFBD>Ƿ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>־
**********************************************************/
int cmhi_get_conntrack_u16(const struct sk_buff *skb, uint16_t *value, cmhi_ext_type type)
{
enum ip_conntrack_info ctinfo = {0};
struct nf_conn *ct = NULL;
if(!value){
printk(KERN_ERR"[CT_API]get-conntrak_u16: value is null\n");
return CMHI_EXT_ERR;
}
if(!skb){
printk(KERN_ERR"[CT_API]get-conntrack_u16: skb is null\n");
return CMHI_EXT_ERR;
}
ct = nf_ct_get(skb, &ctinfo);
if(!ct){
printk(KERN_ERR"[CT_API]get-conntrak_u16: ct is not existed or ct is untracked\n");
return CMHI_EXT_ERR;
}
switch (type)
{
case USER_VERSION:
*value = ct->cmhi.user_version;
break;
case APP_ID:
*value = ct->cmhi.app_id;
break;
default: {
printk(KERN_INFO"[CT_API]get-conntrak_u16: value is not u16\n");
return CMHI_EXT_ERR;
}
}
return CMHI_EXT_OK;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD>ȡct<EFBFBD><EFBFBD>չ<EFBFBD>ֶ<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD>32λ<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:sk_buff, value(<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ֶε<EFBFBD>ָ<EFBFBD><EFBFBD>), type(<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ֶε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ֶ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: <EFBFBD><EFBFBD>ȡ<EFBFBD>Ƿ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>־
**********************************************************/
int cmhi_get_conntrack_u32(const struct sk_buff *skb, uint32_t *value, cmhi_ext_type type)
{
enum ip_conntrack_info ctinfo = {0};
struct nf_conn *ct = NULL;
if(!value){
printk(KERN_ERR"[CT_API]get-conntrak_u32: value is null\n");
return CMHI_EXT_ERR;
}
if(!skb){
printk(KERN_ERR"[CT_API]get-conntrack_u32: skb is null\n");
return CMHI_EXT_ERR;
}
ct = nf_ct_get(skb, &ctinfo);
if(!ct){
printk(KERN_ERR"[CT_API]get-conntrak_u32: ct is not existed or ct is untracked\n");
return CMHI_EXT_ERR;
}
switch (type)
{
case USER_ID:
*value = ct->cmhi.user_id;
break;
case NODE_INDEX:
*value = ct->cmhi.node_index;
break;
case POLICY_VERSION:
*value = ct->cmhi.policy_version;
break;
case ACTION:
*value = ct->cmhi.action;
break;
default: {
printk(KERN_INFO"[CT_API]get-conntrak_u32: value is not u32\n");
return CMHI_EXT_ERR;
}
}
return CMHI_EXT_OK;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:ɾ<EFBFBD><EFBFBD>ct<EFBFBD><EFBFBD>չ<EFBFBD>ֶ<EFBFBD><EFBFBD>е<EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:sk_buff, type(<EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD>ֶε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: ɾ<EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>־
**********************************************************/
int cmhi_del_conntrack(const struct sk_buff *skb, cmhi_ext_type type)
{
enum ip_conntrack_info ctinfo = {0};
struct nf_conn *ct = NULL;
if(!skb){
printk(KERN_ERR"[CT_API]del-conntrack: skb is null\n");
return CMHI_EXT_ERR;
}
ct = nf_ct_get(skb, &ctinfo);
if(!ct){
printk(KERN_ERR"[CT_API]del-conntrak: ct is not existed or ct is untracked\n");
return CMHI_EXT_ERR;
}
switch (type)
{
case USER_ID:
ct->cmhi.user_id = 0;
break;
case USER_VERSION:
ct->cmhi.user_version = 0;
break;
case NODE_INDEX:
ct->cmhi.node_index = 0;
break;
case APP_ID:
ct->cmhi.app_id = 0;
break;
case POLICY_VERSION:
ct->cmhi.policy_version = 0;
break;
case ACTION:
ct->cmhi.action = 0;
break;
default: {
printk(KERN_INFO"[CT_API]del-conntrak: wrong type\n");
return CMHI_EXT_ERR;
}
}
return CMHI_EXT_OK;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ɾ<EFBFBD><EFBFBD>ct<EFBFBD><EFBFBD>չ<EFBFBD>ֶ<EFBFBD><EFBFBD>е<EFBFBD>action<EFBFBD>ֶε<EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: sk_buff, abit(<EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ)
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: ɾ<EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>־
**********************************************************/
int cmhi_del_conntrack_action_by_bit(const struct sk_buff *skb, cmhi_ext_action_bit abit)
{
enum ip_conntrack_info ctinfo = {0};
struct nf_conn *ct = NULL;
if(!skb){
printk(KERN_ERR"[CT_API]del-conntrack_action_by_bit: skb is null\n");
return CMHI_EXT_ERR;
}
ct = nf_ct_get(skb, &ctinfo);
if(!ct){
printk(KERN_ERR"[CT_API]del-conntrack_action_by_bit: ct is not existed or ct is untracked\n");
return CMHI_EXT_ERR;
}
switch (abit)
{
case CMHI_EXT_PASS:
case CMHI_EXT_GOTO_DPI:
ct->cmhi.action &= (~abit);
break;
default: {
printk(KERN_INFO"[CT_API]del-conntrack_action_by_bit: wrong action bit\n");
return CMHI_EXT_ERR;
}
}
return CMHI_EXT_OK;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>tuple<EFBFBD><EFBFBD>ȡhashֵ
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: const struct nf_conntrack_tuple * <EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: u32 hashֵ
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: u32 hashֵ
**********************************************************/
static u32 cmhi_hash_conntrack_raw(const struct nf_conntrack_tuple *tuple)
{
unsigned int n;
u32 seed;
seed = cmhi_seed;
n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32);
return jhash2((u32 *)tuple, n, seed ^
(((__force __u16)tuple->dst.u.all << 16) |
tuple->dst.protonum));
}
/*
static
int cmhi_net_eq(unsigned long ulnet1, unsigned long ulnet2)
{
return ulnet1 == ulnet2;
}
*/
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD>жϴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tuple<EFBFBD>Ͳ<EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ct<EFBFBD>е<EFBFBD>tuple<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>ͬ
* <EFBFBD>ж<EFBFBD>ct<EFBFBD>е<EFBFBD>bitλ<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>ΪIPS_CONFIRMED_BIT
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ct<EFBFBD>д<EFBFBD><EFBFBD><EFBFBD>tuple<EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD>hash<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:struct nf_conntrack_tuple_hash *
* DPI<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tuple: const struct nf_conntrack_tuple *
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: bool<EFBFBD><EFBFBD><EFBFBD><EFBFBD> true or false
**********************************************************/
static bool
cmhi_nf_ct_key_equal(struct nf_conntrack_tuple_hash *h,
const struct nf_conntrack_tuple *tuple)
{
struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
/* A conntrack can be recreated with the equal tuple,
* so we need to check that the conntrack is confirmed
*/
return nf_ct_tuple_equal(tuple, &h->tuple) &&
//nf_ct_zone_equal(ct, zone, NF_CT_DIRECTION(h)) &&
//nf_ct_is_confirmed(ct) &&
//cmhi_net_eq((unsigned long)(nf_ct_net(ct)));
nf_ct_is_confirmed(ct);
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD>жϴ<EFBFBD>ct<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>expired<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ct_general
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>struct nf_conn *
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>:<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: <EFBFBD><EFBFBD>
**********************************************************/
static void cmhi_nf_ct_gc_expired(struct nf_conn *ct)
{
if (!atomic_inc_not_zero(&ct->ct_general.use))
return;
if (nf_ct_should_gc(ct))
nf_ct_kill(ct);
nf_ct_put(ct);
}
/*
* Warning :
* - Caller must take a reference on returned object
* and recheck nf_ct_tuple_equal(tuple, &h->tuple)
*/
static struct nf_conntrack_tuple_hash *
cmhi_nf_conntrack_find(
const struct nf_conntrack_tuple *tuple, u32 hash)
{
struct nf_conntrack_tuple_hash *h;
struct hlist_nulls_head *ct_hash;
struct hlist_nulls_node *n;
unsigned int bucket, hsize;
begin:
nf_conntrack_get_ht(&ct_hash, &hsize);
bucket = reciprocal_scale(hash, hsize);
//printk(KERN_INFO"[CT_API]###bucket=%d\n", bucket);
hlist_nulls_for_each_entry_rcu(h, n, &ct_hash[bucket], hnnode) {
struct nf_conn *ct;
ct = nf_ct_tuplehash_to_ctrack(h);
if (nf_ct_is_expired(ct)) {
cmhi_nf_ct_gc_expired(ct);
continue;
}
if (nf_ct_is_dying(ct))
continue;
if (cmhi_nf_ct_key_equal(h, tuple))
return h;
}
/*
* if the nulls value we got at the end of this lookup is
* not the expected one, we must restart lookup.
* We probably met an item that was moved to another chain.
*/
if (get_nulls_value(n) != bucket) {
//printk(KERN_INFO"[CT_API]nulls_value != bucket, bucket=%d\n\n\n\n", bucket);
goto begin;
}
return NULL;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>DPI<EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tuple<EFBFBD><EFBFBD>hashֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>tuple<EFBFBD><EFBFBD><EFBFBD><EFBFBD>hash
* Ͱ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>ж<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tuple:const struct nf_conntrack_tuple *<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tuple<EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>hashֵ:u32
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: tuple<EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>hashmap<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: tuple<EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>hashmap<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
**********************************************************/
static struct nf_conntrack_tuple_hash *
cmhi_nf_conntrack_find_get(
const struct nf_conntrack_tuple *tuple, u32 hash)
{
struct nf_conntrack_tuple_hash *h;
struct nf_conn *ct;
rcu_read_lock();
begin:
h = cmhi_nf_conntrack_find(tuple, hash);
if (h) {
ct = nf_ct_tuplehash_to_ctrack(h);
if (unlikely(nf_ct_is_dying(ct) ||
!atomic_inc_not_zero(&ct->ct_general.use)))
h = NULL;
else {
if (unlikely(!cmhi_nf_ct_key_equal(h, tuple))) {
nf_ct_put(ct);
goto begin;
}
}
}
rcu_read_unlock();
return h;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>DPI tuple<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>ct
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>DPI<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>tuple<EFBFBD><EFBFBD>ַ: struct dpi_tuple *
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>struct nf_conn *
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: <EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>struct nf_conn *
**********************************************************/
struct nf_conn *get_conntrack_from_tuple(struct dpi_tuple *dpi_tuple)
{
u32 hash;
struct nf_conntrack_tuple tuple = {0};
struct nf_conntrack_tuple_hash *h= NULL;
struct nf_conn *ct = NULL;
if(!dpi_tuple){
printk(KERN_ERR"[CT_API]get-conntrack-from-tuple: dpi_tuple is null.\n");
return NULL;
}
tuple.src.l3num = 2;
tuple.src.u3.ip = dpi_tuple->sip;
tuple.dst.u3.ip = dpi_tuple->dip;
tuple.dst.protonum = dpi_tuple->protonum;
tuple.dst.dir = IP_CT_DIR_ORIGINAL;
/* UDP */
if(dpi_tuple->protonum == IPPROTO_UDP){
tuple.src.u.udp.port = dpi_tuple->sport;
tuple.dst.u.udp.port = dpi_tuple->dport;
}
/* TCP */
if(dpi_tuple->protonum == IPPROTO_TCP){
tuple.src.u.tcp.port = dpi_tuple->sport;
tuple.dst.u.tcp.port = dpi_tuple->dport;
}
printk(KERN_INFO"[CT_API]<L3XXX>:src.l3num=%d, src.u3.ip=%x, dst.u3.ip=%x, dst.protonum=%d, dst.dir=%d,dst.u.all=%d\n",
tuple.src.l3num, tuple.src.u3.ip, tuple.dst.u3.ip, tuple.dst.protonum, tuple.dst.dir, tuple.dst.u.all);
hash = cmhi_hash_conntrack_raw(&tuple);
printk(KERN_INFO"[CT_API]get-conntrack-from-tuple:hash=%d\n", hash);
h = cmhi_nf_conntrack_find_get(&tuple, hash);
if (!h) {
printk(KERN_ERR"[CT_API]get-conntrack-from-tuple: h is null.\n");
return NULL;
}
ct = nf_ct_tuplehash_to_ctrack(h);
return ct;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>id aid<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><EFBFBD><EFBFBD>ct<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><EFBFBD>ٱ<EFBFBD>ָ<EFBFBD><EFBFBD>struct nf_conn *<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>id aid
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: 0<EFBFBD><EFBFBD>-1
**********************************************************/
int __set_aid_by_dpi_tuple(struct nf_conn *ct, uint16_t aid)
{
if(!ct){
printk(KERN_ERR"[CT_API]__set-appid-by-dpituple:input ct is null.\n");
return CMHI_EXT_ERR;
}
if(!ct){
printk(KERN_ERR"[CT_API]__set-appid-by-dpituple: ct is not existed or ct is untracked\n");
return CMHI_EXT_ERR;
}
ct->cmhi.app_id = aid;
return CMHI_EXT_OK;
}
/**********************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>id aid<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><EFBFBD><EFBFBD>ct<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: Ӧ<EFBFBD><EFBFBD>id aid
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ: 0<EFBFBD><EFBFBD>-1
**********************************************************/
int set_aid_by_dpi_tuple(struct dpi *dpi)
{
int ret;
struct nf_conn *ct;
if(!dpi){
printk(KERN_ERR"[CT_API]set-appid-by-dpituple: dpi is null.\n");
return CMHI_EXT_ERR;
}
ct = get_conntrack_from_tuple(&dpi->tuple);
if(!ct){
printk(KERN_ERR"[CT_API]set-appid-by-dpituple:find ct failed, now return.\n");
return CMHI_EXT_ERR;
}
printk(KERN_INFO"[CT_API]set-appid-by-dpituple: Find ct !!!\n");
ret = __set_aid_by_dpi_tuple(ct, dpi->aid);
if(CMHI_EXT_OK != ret){
printk(KERN_ERR"[CT_API]set-appid-by-dpituple:set aid failed.\n");
return CMHI_EXT_ERR;
}
printk(KERN_INFO"[CT_API]set-appid-by-dpituple: set aid ok\n");
return CMHI_EXT_OK;
}
EXPORT_SYMBOL(cmhi_set_conntrack_u16);
EXPORT_SYMBOL(cmhi_set_conntrack_u32);
EXPORT_SYMBOL(cmhi_set_conntrack_action_by_bit);
EXPORT_SYMBOL(cmhi_get_conntrack_u16);
EXPORT_SYMBOL(cmhi_get_conntrack_u32);
EXPORT_SYMBOL(cmhi_del_conntrack);
EXPORT_SYMBOL(cmhi_del_conntrack_action_by_bit);
EXPORT_SYMBOL(get_conntrack_from_tuple);
EXPORT_SYMBOL(set_aid_by_dpi_tuple);
static int __init API_init(void)
{
printk(KERN_INFO"[API]module init.\n");
return 0;
}
static void __exit API_exit(void)
{
printk(KERN_INFO"[API]module exit.\n");
return;
}
module_init(API_init);
module_exit(API_exit);
MODULE_DESCRIPTION("CMHI API");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");