[Feature][ZXW-292]merge P56U06 version

Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I922cf7b03b256d7dd5b0a6b73c3eac813f9512eb
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
index d029388..827cd18 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
@@ -21,12 +21,12 @@
 #ifdef CONFIG_MMU
 #ifdef CONFIG_KPROBES
 static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){int 
-ret=(0x60b+5714-0x1c5d);if(!user_mode(regs)){preempt_disable();if(kprobe_running
-()&&kprobe_fault_handler(regs,fsr))ret=(0x1ddd+219-0x1eb7);preempt_enable();}
-return ret;}
+ret=(0x114a+3398-0x1e90);if(!user_mode(regs)){preempt_disable();if(
+kprobe_running()&&kprobe_fault_handler(regs,fsr))ret=(0x1eab+674-0x214c);
+preempt_enable();}return ret;}
 #else
 static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){return
-(0x97f+2176-0x11ff);}
+(0x7e0+1274-0xcda);}
 #endif
 void show_pte(struct mm_struct*mm,unsigned long addr){pgd_t*pgd;if(!mm)mm=&
 init_mm;printk(KERN_ALERT"\x70\x67\x64\x20\x3d\x20\x25\x70" "\n",mm->pgd);pgd=
@@ -34,10 +34,10 @@
 "\x5b\x25\x30\x38\x6c\x78\x5d\x20\x2a\x70\x67\x64\x3d\x25\x30\x38\x6c\x6c\x78",
 addr,(long long)pgd_val(*pgd));do{pud_t*pud;pmd_t*pmd;pte_t*pte;if(pgd_none(*pgd
 ))break;if(pgd_bad(*pgd)){printk("\x28\x62\x61\x64\x29");break;}pud=pud_offset(
-pgd,addr);if(PTRS_PER_PUD!=(0x122+1182-0x5bf))printk(
+pgd,addr);if(PTRS_PER_PUD!=(0x18b2+1137-0x1d22))printk(
 "\x2c\x20\x2a\x70\x75\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pud_val(*pud))
 ;if(pud_none(*pud))break;if(pud_bad(*pud)){printk("\x28\x62\x61\x64\x29");break;
-}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x45f+5786-0x1af8))printk(
+}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x108c+5353-0x2574))printk(
 "\x2c\x20\x2a\x70\x6d\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pmd_val(*pmd))
 ;if(pmd_none(*pmd))break;if(pmd_bad(*pmd)){printk("\x28\x62\x61\x64\x29");break;
 }if(PageHighMem(pfn_to_page(pmd_val(*pmd)>>PAGE_SHIFT)))break;pte=pte_offset_map
@@ -47,18 +47,18 @@
 printk("\x2c\x20\x2a\x70\x70\x74\x65\x3d\x25\x30\x38\x6c\x6c\x78",(long long)
 pte_val(pte[PTE_HWTABLE_PTRS]));
 #endif
-pte_unmap(pte);}while((0x8ac+5684-0x1ee0));printk("\n");}
+pte_unmap(pte);}while((0x67b+2056-0xe83));printk("\n");}
 #else					
 void show_pte(struct mm_struct*mm,unsigned long addr){}
 #endif					
 static void __do_kernel_fault(struct mm_struct*mm,unsigned long addr,unsigned 
 int fsr,struct pt_regs*regs){if(fixup_exception(regs))return;bust_spinlocks(
-(0x653+1826-0xd74));printk(KERN_ALERT
+(0x11a2+3461-0x1f26));printk(KERN_ALERT
 "\x55\x6e\x61\x62\x6c\x65\x20\x74\x6f\x20\x68\x61\x6e\x64\x6c\x65\x20\x6b\x65\x72\x6e\x65\x6c\x20\x25\x73\x20\x61\x74\x20\x76\x69\x72\x74\x75\x61\x6c\x20\x61\x64\x64\x72\x65\x73\x73\x20\x25\x30\x38\x6c\x78" "\n"
 ,(addr<PAGE_SIZE)?
 "\x4e\x55\x4c\x4c\x20\x70\x6f\x69\x6e\x74\x65\x72\x20\x64\x65\x72\x65\x66\x65\x72\x65\x6e\x63\x65"
 :"\x70\x61\x67\x69\x6e\x67\x20\x72\x65\x71\x75\x65\x73\x74",addr);show_pte(mm,
-addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0x15c4+1884-0x1d20));
+addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0x479+3944-0x13e1));
 do_exit(SIGKILL);}static void __do_user_fault(struct task_struct*tsk,unsigned 
 long addr,unsigned int fsr,unsigned int sig,int code,struct pt_regs*regs){struct
  siginfo si;
@@ -69,7 +69,7 @@
 ,tsk->comm,sig,addr,fsr);show_pte(tsk->mm,addr);show_regs(regs);}
 #endif
 tsk->thread.address=addr;tsk->thread.error_code=fsr;tsk->thread.trap_no=
-(0x474+8687-0x2655);si.si_signo=sig;si.si_errno=(0x1a54+2028-0x2240);si.si_code=
+(0xa29+3854-0x1929);si.si_signo=sig;si.si_errno=(0x1879+829-0x1bb6);si.si_code=
 code;si.si_addr=(void __user*)addr;force_sig_info(sig,&si,tsk);}void do_bad_area
 (unsigned long addr,unsigned int fsr,struct pt_regs*regs){struct task_struct*tsk
 =current;struct mm_struct*mm=tsk->active_mm;if(user_mode(regs))__do_user_fault(
@@ -91,8 +91,8 @@
 static int __kprobes do_page_fault(unsigned long addr,unsigned int fsr,struct 
 pt_regs*regs){struct task_struct*tsk;struct mm_struct*mm;int fault,sig,code;int 
 write=fsr&FSR_WRITE;unsigned int flags=FAULT_FLAG_ALLOW_RETRY|
-FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0x108b+535-0x12a2));if(
-notify_page_fault(regs,fsr))return(0xc28+6774-0x269e);tsk=current;mm=tsk->mm;if(
+FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0xdc9+815-0x10f8));if(
+notify_page_fault(regs,fsr))return(0xbd+7699-0x1ed0);tsk=current;mm=tsk->mm;if(
 interrupts_enabled(regs))local_irq_enable();if(!mm||pagefault_disabled())goto 
 no_context;if(!down_read_trylock(&mm->mmap_sem)){if(!user_mode(regs)&&!
 search_exception_tables(regs->ARM_pc))goto no_context;retry:down_read(&mm->
@@ -101,23 +101,22 @@
 if(!user_mode(regs)&&!search_exception_tables(regs->ARM_pc))goto no_context;
 #endif
 }fault=__do_page_fault(mm,addr,fsr,flags,tsk);if((fault&VM_FAULT_RETRY)&&
-fatal_signal_pending(current))return(0x47b+7514-0x21d5);perf_sw_event(
-PERF_COUNT_SW_PAGE_FAULTS,(0x6b2+4880-0x19c1),regs,addr);if(!(fault&
+fatal_signal_pending(current))return(0x1688+1136-0x1af8);perf_sw_event(
+PERF_COUNT_SW_PAGE_FAULTS,(0x13b5+64-0x13f4),regs,addr);if(!(fault&
 VM_FAULT_ERROR)&&flags&FAULT_FLAG_ALLOW_RETRY){if(fault&VM_FAULT_MAJOR){tsk->
-maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x261+6262-0x1ad6),regs,
+maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x358+6757-0x1dbc),regs,
 addr);}else{tsk->min_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
-(0xc96+1599-0x12d4),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
+(0xab3+4256-0x1b52),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
 FAULT_FLAG_ALLOW_RETRY;goto retry;}}up_read(&mm->mmap_sem);if(likely(!(fault&(
-VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x788+1418-0xd12);if
-(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0x292+2356-0xbc6);}if(!
+VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x1b1+7410-0x1ea3);
+if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0xebd+1384-0x1425);}if(!
 user_mode(regs))goto no_context;if(fault&VM_FAULT_SIGBUS){sig=SIGBUS;code=
 BUS_ADRERR;}else{sig=SIGSEGV;code=fault==VM_FAULT_BADACCESS?SEGV_ACCERR:
-SEGV_MAPERR;}__do_user_fault(tsk,addr,fsr,sig,code,regs);return
-(0x634+3100-0x1250);no_context:__do_kernel_fault(mm,addr,fsr,regs);return
-(0x139+4608-0x1339);}
+SEGV_MAPERR;}__do_user_fault(tsk,addr,fsr,sig,code,regs);return(0x406+121-0x47f)
+;no_context:__do_kernel_fault(mm,addr,fsr,regs);return(0x1c70+1566-0x228e);}
 #else					
 static int do_page_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
-){return(0x49d+7925-0x2392);}
+){return(0x3ec+2023-0xbd3);}
 #endif					
 #ifdef CONFIG_MMU
 static int __kprobes do_translation_fault(unsigned long addr,unsigned int fsr,
@@ -130,21 +129,21 @@
 bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=pmd_offset(pud,addr);
 pmd_k=pmd_offset(pud_k,addr);
 #ifdef CONFIG_ARM_LPAE
-index=(0x46+7137-0x1c27);
+index=(0x1397+1894-0x1afd);
 #else
-index=(addr>>SECTION_SHIFT)&(0x1eb3+1867-0x25fd);
+index=(addr>>SECTION_SHIFT)&(0x1d96+756-0x2089);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0xbaf+221-0xc8c);bad_area:do_bad_area(addr,fsr,regs);return(0x483+4384-0x15a3);
-}
+(0x108+1051-0x523);bad_area:do_bad_area(addr,fsr,regs);return(0x163+4974-0x14d1)
+;}
 #else					
 static int do_translation_fault(unsigned long addr,unsigned int fsr,struct 
-pt_regs*regs){return(0x3f+9187-0x2422);}
+pt_regs*regs){return(0xdfd+2141-0x165a);}
 #endif					
 static int do_sect_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
 ){if(interrupts_enabled(regs))local_irq_enable();do_bad_area(addr,fsr,regs);
-return(0xc97+2506-0x1661);}static int do_bad(unsigned long addr,unsigned int fsr
-,struct pt_regs*regs){return(0x148b+1557-0x1a9f);}struct fsr_info{int(*fn)(
+return(0xde2+4799-0x20a1);}static int do_bad(unsigned long addr,unsigned int fsr
+,struct pt_regs*regs){return(0xacc+1313-0xfec);}struct fsr_info{int(*fn)(
 unsigned long addr,unsigned int fsr,struct pt_regs*regs);int sig;int code;const 
 char*name;};
 #ifdef CONFIG_ARM_LPAE
@@ -153,21 +152,21 @@
 #include "fsr-2level.c"
 #endif
 void __init hook_fault_code(int nr,int(*fn)(unsigned long,unsigned int,struct 
-pt_regs*),int sig,int code,const char*name){if(nr<(0xa89+6866-0x255b)||nr>=
+pt_regs*),int sig,int code,const char*name){if(nr<(0xac2+42-0xaec)||nr>=
 ARRAY_SIZE(fsr_info))BUG();fsr_info[nr].fn=fn;fsr_info[nr].sig=sig;fsr_info[nr].
 code=code;fsr_info[nr].name=name;}
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
 static DECLARE_RWSEM(shrinker_rwsem);atomic_t _code_page_count=ATOMIC_INIT(
-(0x84b+7640-0x2623));struct addr_info{struct list_head node;unsigned long vaddr;
+(0xd8+6514-0x1a4a));struct addr_info{struct list_head node;unsigned long vaddr;
 unsigned long kaddr;unsigned long page_index;};enum modem_access_technology{GSM=
-(0x78c+3841-0x168d),UTRAN=(0x58+487-0x23e),LTE=(0xda1+5834-0x2469),COM=
-(0x271+9109-0x2603),NR_MODEM_ACCESS=(0xef2+4515-0x2091)};struct list_head 
+(0x1b0+2553-0xba9),UTRAN=(0x403+8875-0x26ad),LTE=(0x617+7344-0x22c5),COM=
+(0xa0a+4588-0x1bf3),NR_MODEM_ACCESS=(0x179+7641-0x1f4e)};struct list_head 
 modem_page_list[NR_MODEM_ACCESS]={LIST_HEAD_INIT(modem_page_list[
-(0x18c0+2014-0x209e)]),LIST_HEAD_INIT(modem_page_list[(0xcfb+2710-0x1790)]),
-LIST_HEAD_INIT(modem_page_list[(0xb3c+587-0xd85)]),LIST_HEAD_INIT(
-modem_page_list[(0x826+2696-0x12ab)]),};unsigned int page_used[
-(0x126b+360-0x13ab)];struct completion page_completion[(0xa44+2553-0x1415)*
-(0x60f+2973-0x118c)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
+(0xb6c+4798-0x1e2a)]),LIST_HEAD_INIT(modem_page_list[(0x1529+4480-0x26a8)]),
+LIST_HEAD_INIT(modem_page_list[(0x226+4890-0x153e)]),LIST_HEAD_INIT(
+modem_page_list[(0x4a5+8026-0x23fc)]),};unsigned int page_used[
+(0x1018+1513-0x15d9)];struct completion page_completion[(0x13bc+3080-0x1f9c)*
+(0xac7+5959-0x21ee)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
 unsigned long end){pte_t*pte;pte=pte_offset_kernel(pmd,addr);do{pte_t ptent=
 ptep_get_and_clear(&init_mm,addr,pte);WARN_ON(!pte_none(ptent)&&!pte_present(
 ptent));}while(pte++,addr+=PAGE_SIZE,addr!=end);}static void unmap_pmd_range(
@@ -181,14 +180,14 @@
 addr,unsigned long end){pgd_t*pgd;unsigned long next;BUG_ON(addr>=end);pgd=
 pgd_offset_k(addr);do{next=pgd_addr_end(addr,end);if(pgd_none_or_clear_bad(pgd))
 continue;unmap_pud_range(pgd,addr,next);}while(pgd++,addr=next,addr!=end);}void 
-shrink_modem_mem(unsigned int access_type){int i=(0x15f2+2230-0x1ea8);unsigned 
+shrink_modem_mem(unsigned int access_type){int i=(0x198c+2272-0x226c);unsigned 
 long vaddr;struct addr_info*addr,*tmp_addr;struct list_head tmp_page_list;for(i=
-(0xd8a+5819-0x2445);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write
+(0x9da+6393-0x22d3);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write
 (&shrinker_rwsem);list_replace_init(&modem_page_list[i],&tmp_page_list);up_write
 (&shrinker_rwsem);list_for_each_entry_safe(addr,tmp_addr,&tmp_page_list,node){
 list_del_init(&addr->node);page_completion[addr->page_index].done=
-(0x26+6388-0x191a);page_used[addr->page_index/BITS_PER_LONG]&=~(
-(0xf91+359-0x10f7)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
+(0xc20+2903-0x1777);page_used[addr->page_index/BITS_PER_LONG]&=~(
+(0x1b4+1550-0x7c1)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
 PAGE_MASK;if(vaddr<cpps_global_var.cpko_text_start||vaddr>cpps_global_var.
 modem_text_end){panic(
 "\x61\x64\x64\x72\x5f\x69\x6e\x66\x6f\x3a\x20\x25\x30\x38\x78\x20\x69\x73\x20\x20\x64\x65\x73\x74\x72\x6f\x79"
@@ -196,52 +195,53 @@
 PAGE_SIZE);flush_tlb_kernel_range(vaddr,vaddr+PAGE_SIZE);
 #ifdef CONFIG_DEBUG_RODATA
 unsigned int flags;local_irq_save(flags);set_memory_rw(addr->kaddr,
-(0xc12+2869-0x1746));local_irq_restore(flags);
+(0xf94+2221-0x1840));local_irq_restore(flags);
 #endif
 free_page(addr->kaddr);kfree(addr);atomic_dec(&_code_page_count);};}}
 EXPORT_SYMBOL(shrink_modem_mem);phys_addr_t virt_is_mapping(unsigned long addr){
 pgd_t*pgd;pmd_t*pmd;pte_t*ptep,pte;unsigned long pfn;pgd=pgd_offset_k(addr);if(!
 pgd_none(*pgd)){pmd=pmd_offset(pgd,addr);if(!pmd_none(*pmd)){ptep=pte_offset_map
 (pmd,addr);pte=*ptep;if(pte_present(pte)){pfn=pte_pfn(pte);return __pfn_to_phys(
-pfn);}}}return(0xc20+6314-0x24ca);}static int sync_pgd(unsigned long addr,
-unsigned int fsr,struct pt_regs*regs){unsigned int index;pgd_t*pgd,*pgd_k;pud_t*
-pud,*pud_k;pmd_t*pmd,*pmd_k;index=pgd_index(addr);pgd=cpu_get_pgd()+index;pgd_k=
+pfn);}}}return(0x836+727-0xb0d);}static int sync_pgd(unsigned long addr,unsigned
+ int fsr,struct pt_regs*regs){unsigned int index;pgd_t*pgd,*pgd_k;pud_t*pud,*
+pud_k;pmd_t*pmd,*pmd_k;index=pgd_index(addr);pgd=cpu_get_pgd()+index;pgd_k=
 init_mm.pgd+index;if(pgd_none(*pgd_k))goto bad_area;if(!pgd_present(*pgd))
 set_pgd(pgd,*pgd_k);pud=pud_offset(pgd,addr);pud_k=pud_offset(pgd_k,addr);if(
 pud_none(*pud_k))goto bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=
 pmd_offset(pud,addr);pmd_k=pmd_offset(pud_k,addr);
 #ifdef CONFIG_ARM_LPAE
-index=(0x1815+614-0x1a7b);
+index=(0x1a4+8803-0x2407);
 #else
-index=(addr>>SECTION_SHIFT)&(0xc29+5320-0x20f0);
+index=(addr>>SECTION_SHIFT)&(0xa04+956-0xdbf);
 #endif
 if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0x169+230-0x24f);bad_area:do_bad_area(addr,fsr,regs);return(0x18a+7269-0x1def);
-}unsigned long*read_code_file(unsigned long page_index){unsigned long*code_buf;
-ssize_t result;code_buf=get_zeroed_page(GFP_ATOMIC);if(!code_buf)panic(
+(0x6d6+5237-0x1b4b);bad_area:do_bad_area(addr,fsr,regs);return
+(0x32d+4382-0x144b);}unsigned long*read_code_file(unsigned long page_index){
+unsigned long*code_buf;ssize_t result;code_buf=get_zeroed_page(GFP_ATOMIC);if(!
+code_buf)panic(
 "\x6d\x65\x6d\x65\x6f\x72\x79\x20\x6e\x6f\x74\x20\x65\x6e\x6f\x75\x67\x68\x21\x21"
 );atomic_inc(&_code_page_count);if(IS_ERR(cpps_global_var.fp_code)||
 cpps_global_var.fp_code==NULL){panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}
 mm_segment_t old_fs;old_fs=get_fs();set_fs(KERNEL_DS);loff_t pos;pos=page_index*
 PAGE_SIZE+cpps_global_var.modem_offset;result=vfs_read(cpps_global_var.fp_code,(
-char*)code_buf,PAGE_SIZE,&pos);if(result<(0xa86+2767-0x1555)){panic(
+char*)code_buf,PAGE_SIZE,&pos);if(result<(0x150+4607-0x134f)){panic(
 "\x72\x65\x61\x64\x20\x63\x6f\x64\x65\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n"
 );}
 #ifdef CONFIG_DEBUG_RODATA
 unsigned int flags;local_irq_save(flags);set_memory_ro((unsigned long)code_buf,
-(0x60c+2436-0xf8f));local_irq_restore(flags);
+(0x11a9+599-0x13ff));local_irq_restore(flags);
 #endif
 set_fs(old_fs);return code_buf;}void read_code_mapping(unsigned long addr,
 unsigned int fsr,struct pt_regs*regs){unsigned long offset;unsigned long vaddr;
 const struct mem_type*mtype;unsigned long*vir_codebuf;unsigned long page_index;
-unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=(0x172+9478-0x2678)
+unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=(0x13df+559-0x160e)
 ){sync_pgd(addr&PAGE_MASK,fsr,regs);return;}vaddr=addr&PAGE_MASK;offset=vaddr&(~
 cpps_global_var.cpko_text_start);page_index=offset>>PAGE_SHIFT;page_shift=
 page_index%BITS_PER_LONG;if((page_used[page_index/BITS_PER_LONG]>>page_shift)&
-(0x1e57+173-0x1f03)){wait_for_completion(&page_completion[page_index]);sync_pgd(
-vaddr,fsr,regs);return;}else page_used[page_index/BITS_PER_LONG]|=(
-(0x1126+2074-0x193f)<<page_shift);local_irq_enable();vir_codebuf=read_code_file(
+(0x12bc+1894-0x1a21)){wait_for_completion(&page_completion[page_index]);sync_pgd
+(vaddr,fsr,regs);return;}else page_used[page_index/BITS_PER_LONG]|=(
+(0x569+7857-0x2419)<<page_shift);local_irq_enable();vir_codebuf=read_code_file(
 page_index);struct addr_info*addr_info;addr_info=kzalloc(sizeof(struct addr_info
 ),GFP_KERNEL);addr_info->kaddr=vir_codebuf;addr_info->vaddr=addr;addr_info->
 page_index=page_index;down_write(&shrinker_rwsem);if(vaddr<cpps_global_var.
@@ -259,46 +259,46 @@
 struct pt_regs*regs){const struct fsr_info*inf=fsr_info+fsr_fs(fsr);struct 
 siginfo info;
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0x718+1707-0xdc3)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x69a+8178-0x268c)&&addr>=cpps_global_var.cpko_text_start&&addr<=
 cpps_global_var.modem_text_end){read_code_mapping(addr,fsr&~FSR_LNX_PF,regs);
 return;}
 #endif
 if(!inf->fn(addr,fsr&~FSR_LNX_PF,regs))return;printk(KERN_ALERT
 "\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x66\x61\x75\x6c\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0xced+4656-0x1f1d);
+,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0xda2+2052-0x15a6);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,fsr,(0x1da4+1718-0x245a));}void __init hook_ifault_code(int nr,int(*fn)(
+info,fsr,(0x32b+7125-0x1f00));}void __init hook_ifault_code(int nr,int(*fn)(
 unsigned long,unsigned int,struct pt_regs*),int sig,int code,const char*name){if
-(nr<(0x22b7+286-0x23d5)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
+(nr<(0x4d2+3103-0x10f1)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
 ifsr_info[nr].sig=sig;ifsr_info[nr].code=code;ifsr_info[nr].name=name;}
 asmlinkage void __exception do_PrefetchAbort(unsigned long addr,unsigned int 
 ifsr,struct pt_regs*regs){const struct fsr_info*inf=ifsr_info+fsr_fs(ifsr);
 struct siginfo info;
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0x1130+3439-0x1e9f)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x1606+969-0x19cf)&&addr>=cpps_global_var.cpko_text_start&&addr<=
 cpps_global_var.modem_text_end){read_code_mapping(addr,ifsr|FSR_LNX_PF,regs);
 return;}
 #endif
 if(!inf->fn(addr,ifsr|FSR_LNX_PF,regs))return;printk(KERN_ALERT
 "\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x70\x72\x65\x66\x65\x74\x63\x68\x20\x61\x62\x6f\x72\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x9f3+3018-0x15bd);
+,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x40a+8413-0x24e7);
 info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,ifsr,(0x3c0+6757-0x1e25));}
+info,ifsr,(0x799+7053-0x2326));}
 #ifndef CONFIG_ARM_LPAE
 static int __init exceptions_init(void){if(cpu_architecture()>=CPU_ARCH_ARMv6){
-hook_fault_code((0x498+7309-0x2121),do_translation_fault,SIGSEGV,SEGV_MAPERR,
+hook_fault_code((0x26d+7331-0x1f0c),do_translation_fault,SIGSEGV,SEGV_MAPERR,
 "\x49\x2d\x63\x61\x63\x68\x65\x20\x6d\x61\x69\x6e\x74\x65\x6e\x61\x6e\x63\x65\x20\x66\x61\x75\x6c\x74"
-);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0x17f8+1076-0x1c29),
+);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0xd56+3178-0x19bd),
 do_bad,SIGSEGV,SEGV_MAPERR,
 "\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
-);hook_fault_code((0x9a1+5338-0x1e75),do_bad,SIGSEGV,SEGV_MAPERR,
+);hook_fault_code((0x6eb+238-0x7d3),do_bad,SIGSEGV,SEGV_MAPERR,
 "\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
 );}
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
-int index=(0x178f+658-0x1a21);for(index=(0xb3f+3361-0x1860);index<
-(0xebc+5035-0x223f)*(0x629+8093-0x25a6);index++)init_completion(&page_completion
-[index]);
+int index=(0x42c+8565-0x25a1);for(index=(0xfe3+4417-0x2124);index<
+(0xfc+2608-0xb04)*(0xfb5+3946-0x1eff);index++)init_completion(&page_completion[
+index]);
 #endif
-return(0x1a9a+1781-0x218f);}arch_initcall(exceptions_init);
+return(0xc0d+494-0xdfb);}arch_initcall(exceptions_init);
 #endif
 
diff --git a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
index 777b790..e77e5fe 100755
--- a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
+++ b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
@@ -86,30 +86,30 @@
 __comm_modem_text_start;unsigned int modem_text_end;unsigned int cpko_data_start
 ;unsigned int cpko_bss_start;unsigned int cpko_text_offset;}cpko_section_layout;
 cpko_section_layout cpko_ps_section;int raise(int signo){return
-(0x14ad+4132-0x24d1);}extern unsigned int SysEntry(void);static int 
+(0x9e6+3955-0x1959);}extern unsigned int SysEntry(void);static int 
 ko_Main_Thread(void*data){struct sched_param param={.sched_priority=
-MAX_USER_RT_PRIO/(0x1e3f+2197-0x26d2)-(0xe89+382-0x1004)};int ret=
-(0x190c+975-0x1cdb);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry()
-;if(ret!=(0x537+901-0x8bc))panic("Main_Thread\n");param.sched_priority=
-MAX_USER_RT_PRIO-(0xb0d+4704-0x1d3f);sched_setscheduler(kthreadd_task,SCHED_FIFO
-,&param);return(0x1ab1+2741-0x2566);}int zte_modem_ko_start(void){kthread_run(
+MAX_USER_RT_PRIO/(0x19ec+1080-0x1e22)-(0x1448+357-0x15aa)};int ret=
+(0x20f+6386-0x1b01);sched_setscheduler(current,SCHED_FIFO,&param);ret=SysEntry()
+;if(ret!=(0x381+2774-0xe57))panic("Main_Thread\n");param.sched_priority=
+MAX_USER_RT_PRIO-(0x839+7013-0x2370);sched_setscheduler(kthreadd_task,SCHED_FIFO
+,&param);return(0xef+5068-0x14bb);}int zte_modem_ko_start(void){kthread_run(
 ko_Main_Thread,NULL,"\x5a\x54\x45\x4d\x61\x69\x6e\x54\x68\x72\x65\x61\x64");
-return(0x1607+1856-0x1d47);}static void cpko_sectioninfo_set(void){int ret;
-struct file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x830+181-0x8e5);struct 
+return(0x12ac+2426-0x1c26);}static void cpko_sectioninfo_set(void){int ret;
+struct file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x8bd+6473-0x2206);struct 
 cpps_globalModem globalVar;fp=filp_open(
 "\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x5f\x73\x65\x63\x69\x6e\x66\x6f\x2e\x62\x69\x6e"
-,(0x114a+2841-0x1c63),(0x1c4f+376-0x1dc7));if(IS_ERR(fp)||fp==NULL)panic(
+,(0x81a+3218-0x14ac),(0x1263+2589-0x1c80));if(IS_ERR(fp)||fp==NULL)panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");old_fs=
 get_fs();set_fs(KERNEL_DS);ret=vfs_read(fp,(char*)&cpko_ps_section,sizeof(
-cpko_section_layout),&cpko_pos);if(ret<=(0xb13+4204-0x1b7f))panic(
+cpko_section_layout),&cpko_pos);if(ret<=(0xa02+7211-0x262d))panic(
 "\x72\x65\x61\x64\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");filp_close(
 fp,NULL);
 #ifdef CONFIG_MODEM_CODE_IS_MAPPING
 fp=filp_open(
 "\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x2e\x6b\x6f",
-(0x1397+2226-0x1c49),(0x185+4317-0x1262));if(IS_ERR(fp)||fp==NULL)panic(
+(0xaf4+502-0xcea),(0xe41+3977-0x1dca));if(IS_ERR(fp)||fp==NULL)panic(
 "\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");fp->f_ra.
-ra_pages=(0x9f0+3506-0x17a2);
+ra_pages=(0x370+4606-0x156e);
 #endif
 if(cpko_ps_section.cpko_text_start){globalVar.cpko_text_start=(unsigned long)
 cpko_ps_section.cpko_text_start;globalVar.cpko_rodata_start=(unsigned long)
@@ -129,7 +129,7 @@
 vfree_modem_section(globalVar.cpko_text_start,globalVar.modem_text_end);
 #endif
 }else panic("\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}static int 
-cpko_start(void){struct cpps_callbacks callback={(0x259+3423-0xfb8)};callback.
+cpko_start(void){struct cpps_callbacks callback={(0xef6+2228-0x17aa)};callback.
 zOss_ResetNVFactory=zOss_ResetNVFactory;callback.zOss_NvramFlush=zOss_NvramFlush
 ;callback.zOss_NvItemWrite=zOss_NvItemWrite;callback.zOss_NvItemWriteFactory=
 zOss_NvItemWriteFactory;callback.zOss_NvItemRead=zOss_NvItemRead;callback.
@@ -205,5 +205,5 @@
 psm_GetModemSleepFlagStatus=psm_GetModemSleepFlagStatus;
 #endif
 cpps_callbacks_register(&callback);cpko_sectioninfo_set();zte_modem_ko_start();
-return(0xa14+3188-0x1688);}static int cpko_stop(void){return(0xc55+2097-0x1486);
+return(0x562+5820-0x1c1e);}static int cpko_stop(void){return(0x4bc+6970-0x1ff6);
 }module_init(cpko_start);module_exit(cpko_stop);
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_tx.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_tx.c
index 3424522..fba633f 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_tx.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800/rwnx_tx.c
@@ -690,8 +690,8 @@
         sw_txhdr->need_cfm = 0;
             sw_txhdr->desc.host.status_desc_addr = 0;
 
-        //sw_txhdr->rwnx_vif->net_stats.tx_packets++;
-        //sw_txhdr->rwnx_vif->net_stats.tx_bytes += sw_txhdr->frame_len;
+        sw_txhdr->rwnx_vif->net_stats.tx_packets++;
+        sw_txhdr->rwnx_vif->net_stats.tx_bytes += sw_txhdr->frame_len;
         rwnx_hw->stats.last_tx = jiffies;
     }
     #else
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/rwnx_tx.c b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/rwnx_tx.c
index de79775..ed80ff5 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/rwnx_tx.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/wireless/aic8800d80l/rwnx_tx.c
@@ -690,8 +690,8 @@
         sw_txhdr->need_cfm = 0;
         sw_txhdr->desc.host.status_desc_addr = 0;
 
-        //sw_txhdr->rwnx_vif->net_stats.tx_packets++;
-        //sw_txhdr->rwnx_vif->net_stats.tx_bytes += sw_txhdr->frame_len;
+        sw_txhdr->rwnx_vif->net_stats.tx_packets++;
+        sw_txhdr->rwnx_vif->net_stats.tx_bytes += sw_txhdr->frame_len;
         rwnx_hw->stats.last_tx = jiffies;
     }
     #else
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
index d1fabea..d2286ca 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
@@ -8,6 +8,7 @@
 #include <linux/ip.h>

 #include <linux/ipv6.h>

 #include <net/addrconf.h>

+#include <net/xfrm.h>

 #include "zvnet_dev.h"

 

 /*******************************************************************************

@@ -34,7 +35,22 @@
 	unsigned short data_off;//ºË¼ä´«µÝÀ´µÄÊý¾Ý°üÊ×µØÖ·£¬Ö¸ÏòMACÖ¡Í·;ÎïÀíµØÖ·

 	unsigned short len;//Êý¾Ý°üÓÐЧ³¤¶È£¬Ò»°ãΪMACÖ¡³¤¶È

 	unsigned short end_off;//end offset

-	unsigned short dev;//cid 1->8

+	unsigned char dev;//cid 1->8

+	unsigned char flag;//0ÆÕͨ°ü£¬1¶þ´Îת·¢°ü£¬2¶þ´Îfastת·¢°ü

+};

+struct	T_zvnet_pkt_stats

+{

+	unsigned int pkt;

+	unsigned int len;

+};

+//AP´«µÝ¸øCAPµÄCTÐÅÏ¢£¬¸ÃÄÚÈÝдÈë¹²ÏíDDR

+struct	T_zvnet_rpmsg_ctstat

+{

+	void *cap_nfct;

+	unsigned char in;

+	unsigned char out;

+	unsigned short flag;

+	struct	T_zvnet_pkt_stats pkt[2];

 };

 /*******************************************************************************

  *						   Local variable definitions					*

@@ -51,7 +67,6 @@
 struct semaphore g_zvnet_free_sem;

 struct semaphore g_zvnet_xmit_sem;

 struct sk_buff_head g_zvnet_skb_xmit_queue;

-

 unsigned int g_wrap_packet_size = 1000;

 module_param(g_wrap_packet_size, int, 0644);

 unsigned int g_wrap_num = 10;

@@ -76,6 +91,8 @@
 extern int skb_num_limit;

 extern struct kmem_cache *skbuff_head_cache;

 extern void dma_cache_maint(const void *vir_addr, const void *phy_addr, size_t size, int direction);

+extern void invalid_cache(unsigned char *data,int len);

+extern void fast_update_status_by_capct(void);

 /*******************************************************************************

  *					   Local function declarations						*

  ******************************************************************************/

@@ -138,6 +155,67 @@
 	}

 }

 

+void cap_conntrack_put(void *nfct, int times)

+{

+	if(nfct){

+		T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

+								.chID = channel_21,

+								.flag = RPMSG_WRITE_INT};

+		struct	T_zvnet_rpmsg_ctstat buf = {0};

+		int i = 0;

+		

+		buf.cap_nfct=nfct;

+		msg.buf = &buf;

+		msg.len = sizeof(buf);

+		zv_info("tofree %d nfct=%x", times, nfct);

+		for(i = 0; i < times; i++){

+			zvnetWriteLockIrq(&msg);

+		}

+	}

+}

+

+void cap_conntrack_update(void *nfct, unsigned int pkt0, unsigned int len0, unsigned int pkt1, unsigned int len1, unsigned char in, unsigned char out)

+{

+	T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

+							.chID = channel_21,

+							.flag = 0};

+	struct	T_zvnet_rpmsg_ctstat buf = {0};

+	

+	buf.cap_nfct=nfct;

+	buf.in = in;

+	buf.out = out;

+	buf.flag = 1;

+	buf.pkt[0].pkt = pkt0;

+	buf.pkt[0].len = len0;

+	buf.pkt[1].pkt = pkt1;

+	buf.pkt[1].len = len1;

+	msg.buf = &buf;

+	msg.len = sizeof(buf);

+	zv_info("toupdate0 %d %d %d %d nfct=%x %d %d", pkt0,len0,pkt1,len1, nfct, in, out);

+	zvnetWriteLockIrq(&msg);

+}

+

+void cap_conntrack_update_end(void *nfct, unsigned int pkt0, unsigned int len0, unsigned int pkt1, unsigned int len1, unsigned char in, unsigned char out)

+{

+	T_ZDrvRpMsg_Msg msg = { .actorID = CAP_ID,

+							.chID = channel_21,

+							.flag = RPMSG_WRITE_INT};

+	struct	T_zvnet_rpmsg_ctstat buf = {0};

+	

+	buf.cap_nfct=nfct;

+	buf.in = in;

+	buf.out = out;

+	buf.flag = 1;

+	buf.pkt[0].pkt = pkt0;

+	buf.pkt[0].len = len0;

+	buf.pkt[1].pkt = pkt1;

+	buf.pkt[1].len = len1;

+	msg.buf = &buf;

+	msg.len = sizeof(buf);

+	zv_info("toupdate1 %d %d %d %d nfct=%x %d %d", pkt0,len0,pkt1,len1, nfct, in, out);

+	zvnetWriteLockIrq(&msg);

+}

+

 int zvnet_get_index_by_netdev(struct net_device *net)

 {

     int i;

@@ -243,6 +321,60 @@
 	unsigned int size;

 	int          len;

 	zv_info("build 0x%x 0x%x %d %d", pbuf_temp->buff, pbuf_temp->head, pbuf_temp->data_off, pbuf_temp->len);

+	if(pbuf_temp->flag){

+		skb = (struct sk_buff *)pbuf_temp->buff;

+		skb_unlink(skb, &g_zvnet_skb_queue);

+		skb_dst_drop(skb);

+#ifdef CONFIG_XFRM

+		secpath_put(skb->sp);

+		skb->sp = NULL;

+#endif

+#if IS_ENABLED(CONFIG_NF_CONNTRACK)

+		if(pbuf_temp->flag == 2){

+			skb->nfct_bak = skb->nfct;

+			skb->capNfct = pbuf_temp->head;

+			skb->zvnet_id = zvnet_get_index_by_netdev(skb->dev)+1;

+		}else

+			nf_conntrack_put(skb->nfct);

+		skb->nfct = NULL;

+#endif

+#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED

+		nf_conntrack_put_reasm(skb->nfct_reasm);

+		skb->nfct_reasm = NULL;

+#endif

+#ifdef CONFIG_BRIDGE_NETFILTER

+		nf_bridge_put(skb->nf_bridge);

+		skb->nf_bridge = NULL;

+#endif

+	/* XXX: IS this still necessary? - JHS */

+#ifdef CONFIG_NET_SCHED

+		skb->tc_index = 0;

+#ifdef CONFIG_NET_CLS_ACT

+		skb->tc_verd = 0;

+#endif

+#endif

+		if(skb->len != pbuf_temp->len || skb->data - skb->head != pbuf_temp->data_off){

+			zv_err("err skb=0x%x %d=%d %d=%d", skb, skb->len, pbuf_temp->len, skb->data - skb->head, pbuf_temp->data_off);

+			if(pbuf_temp->len == 0 || pbuf_temp->len > 2000)

+				panic("len	  ERR!!!!!!!!!!\n");

+			skb->data = skb->head + pbuf_temp->data_off;

+			skb_reset_tail_pointer(skb);

+			skb->tail += pbuf_temp->len;

+			//skb->len = pbuf_temp->len;

+			skb->end = skb->head + pbuf_temp->end_off;

+			skb_reset_network_header(skb);

+		}

+		memset(skb, 0, offsetof(struct sk_buff, capHead));

+		skb->len = pbuf_temp->len;

+		skb->isTocap = 0;

+		invalid_cache(skb->head, pbuf_temp->end_off + sizeof(struct skb_shared_info));

+		skb->dev = zvnet_dev[pbuf_temp->dev].net;

+		if(IFF_NOARP & skb->dev->flags)

+			memcpy(skb->data, skb->dev->dev_addr, 6);

+		shinfo = skb_shinfo(skb);

+		atomic_set(&shinfo->dataref, 1);

+		return skb;

+	}

 	if((unsigned long )pbuf_temp->head < DDR_BASE_CAP_ADDR_PA){// || (unsigned long )pbuf_temp->head > (DDR_BASE_CAP_ADDR_PA + DDR_BASE_LEN_CAP)

 		zv_err("err 0x%x 0x%x %d %d", pbuf_temp->buff, pbuf_temp->head, pbuf_temp->data_off, pbuf_temp->len);

 		panic("addr is not CAPBUF mem!!!");

@@ -1088,6 +1220,17 @@
 	return 0;

 }

 #endif

+

+static int zvnet_update_thread(void * nouse)

+{

+	while(1) {

+		if(pcu_CoreIsActive(2))

+			fast_update_status_by_capct();

+		msleep(1000);

+	}

+	zv_err("The update thread exit!");

+	return 0;

+}

 /*******************************************************************************

  *					 Global function implementations						*

  ******************************************************************************/

@@ -1146,7 +1289,17 @@
 	{

 	    struct task_struct *th = NULL;

 	    int retval = 0;

-		

+	    retval = zvnet_createIcpChannel(CAP_ID, channel_21, ICP_CHANNEL_SIZE);

+	    if(retval < 0) {

+	        zv_err("Create IcpChannel channel_21 fail.");

+	        return retval;

+	    }

+

+	    th = kthread_run(zvnet_update_thread, 0, "zvnet-update%d", channel_21);

+	    if (IS_ERR(th)) {

+	        zv_err("Unable to start update thread.");

+	        return PTR_ERR(th);

+	    }

 	    retval = zvnet_createIcpChannel(CAP_ID, channel_20, ICP_CHANNEL_SIZE);

 	    if(retval < 0) {

 	        zv_err("Create IcpChannel channel_20 fail.");

@@ -1177,7 +1330,7 @@
 	        zv_err("Unable to start xmit_warp thread.");

 	        return PTR_ERR(th);

 	    }

-		

+

 	    th = kthread_run(zvnet_free_warp_thread, 0, "zvnet-free-wrap");

 	    if (IS_ERR(th)) {

 	        zv_err("Unable to start free_warp thread.");

diff --git a/ap/os/linux/linux-3.4.x/include/linux/mem_tracker_def.h b/ap/os/linux/linux-3.4.x/include/linux/mem_tracker_def.h
index ed50e56..1fc7fa3 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/mem_tracker_def.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/mem_tracker_def.h
@@ -7,7 +7,8 @@
 #define MEM_FALSE                 (0)
 #define MEM_TRUE                  (1)
 
-#define HEAP_SUFFIX_SIZE  				(2 * (sizeof(size_t)))
+// #define HEAP_SUFFIX_SIZE  				(2 * (sizeof(size_t)))
+#define HEAP_SUFFIX_SIZE  				(64)
 #define KMALLOC_SETUP(base)  			((void *)((unsigned long)(base) + HEAP_SUFFIX_SIZE))
 #define KMALLOC_SET_ENTRY(base, entry)	(*(size_t *)(base) = (entry))
 #define KMALLOC_ORIGINAL_SIZE(size)     ((size)- HEAP_SUFFIX_SIZE)
diff --git a/ap/os/linux/linux-3.4.x/include/linux/skbuff.h b/ap/os/linux/linux-3.4.x/include/linux/skbuff.h
index 3a6199c..17ee513 100755
--- a/ap/os/linux/linux-3.4.x/include/linux/skbuff.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/skbuff.h
@@ -559,8 +559,13 @@
 		__u32		dropcount;
 		__u32		reserved_tailroom;
 	};
+#if _USE_VEHICLE_DC
 	void * capHead;
+	void * capNfct;
+	int zvnet_id;
+	struct nf_conntrack *nfct_bak;
 	unsigned char		 isTocap; //µ±Îª1ʱ£¬±íʾdataÒÑת·¢capºË£¬²»ÓÃÊÍ·Å
+#endif	
 	//sunquan£¬Á㿽±´¼°cache»úÖÆ
 	unsigned char		 isExtern;  //µ±Îª1ʱ£¬±íʾdataÀ´Ô´ÓÚÍⲿºË£»
 	unsigned char		 isFastnat; //µ±Îª1ʱ£¬±íʾ¸ÃÊý¾Ý°ü³É¹¦½øÐÐת·¢Àà¿ìËÙת·¢£»
diff --git a/ap/os/linux/linux-3.4.x/include/net/SI/fast_common.h b/ap/os/linux/linux-3.4.x/include/net/SI/fast_common.h
index 0061759..5fbb61a 100755
--- a/ap/os/linux/linux-3.4.x/include/net/SI/fast_common.h
+++ b/ap/os/linux/linux-3.4.x/include/net/SI/fast_common.h
@@ -131,10 +131,10 @@
     u_int32_t     nat_addr;
     u_int16_t     nat_port;
     //u_int8_t      flow_lbl[3];
-    u_int8_t      type;
     u_int8_t      dmac[ETH_ALEN];
+    u_int8_t      type;
     u_int8_t      tos;
-    u_int8_t      pad;
+    //u_int8_t      pad;
     u_int32_t     priority;
     u_int32_t     mark;
     struct net_device *indev;
@@ -143,9 +143,13 @@
 
     //Èç¹ûÊÇethÀàÐÍ£¬Ôò´Ë´¦±£´æMACÍ·£¬ÒÔ¿ìËÙʵÏÖMACÍ·¸³Öµ
     u_int8_t            hh_flag;
-    unsigned char        hh_data[14];
-    
     u_int8_t       is_not_nat; //Ϊ1£¬±íʾ²»Ö§³ÖNAT
+    unsigned char        hh_data[14];
+#if _USE_VEHICLE_DC
+    atomic_t pkt;
+    atomic_t len;
+    u_int8_t zvnet_id;
+#endif
 }fast_entry_data_t;
 
 typedef struct fast_entry_s{
@@ -160,6 +164,10 @@
     int ackdrop_num;                //ÒѶªÆúµÄack±¨ÎĸöÊý
     struct sk_buff *predrop_skb;    //¼Ç¼×î½üÒ»´Î»º´æµÄakc±¨ÎÄ
     unsigned long ackstart_tick;    //Ò»¸ö¶ªack°üÖÜÆÚµÄÆðʼʱ¿Ìµã
+#if _USE_VEHICLE_DC
+	struct fast_entry_s *fwd_entry;
+	void *cap_nfct;
+#endif
 }fast_entry_t;
 
 typedef struct fast_list_s{
@@ -362,6 +370,8 @@
 uint32_t ipv4_pseudo_header_checksum(const struct iphdr *ip, uint16_t len);
 
 uint16_t ip_checksum_adjust(uint16_t checksum, uint32_t old_hdr_sum, uint32_t new_hdr_sum);
-
+extern void cap_conntrack_put(void *nfct, int times);
+extern void cap_conntrack_update(void *nfct, unsigned int pkt0, unsigned int len0, unsigned int pkt1, unsigned int len1, unsigned char in, unsigned char out);
+extern void cap_conntrack_update_end(void *nfct, unsigned int pkt0, unsigned int len0, unsigned int pkt1, unsigned int len1, unsigned char in, unsigned char out);
 #endif //_FAST_COMMON_H
 
diff --git a/ap/os/linux/linux-3.4.x/include/net/netfilter/nf_conntrack.h b/ap/os/linux/linux-3.4.x/include/net/netfilter/nf_conntrack.h
old mode 100644
new mode 100755
index ae594df..da2454d
--- a/ap/os/linux/linux-3.4.x/include/net/netfilter/nf_conntrack.h
+++ b/ap/os/linux/linux-3.4.x/include/net/netfilter/nf_conntrack.h
@@ -157,6 +157,7 @@
     struct conn_skbinfo packet_info[IP_CT_DIR_MAX];
     struct fast_ct_ext fast_ct;
     struct conn_seq_track conn_pktloss[IP_CT_DIR_MAX];
+	void *fast_entry;
 };
 
 static inline struct nf_conn *
diff --git a/ap/os/linux/linux-3.4.x/mm/mem_tracker.c b/ap/os/linux/linux-3.4.x/mm/mem_tracker.c
index 3963763..c823e9c 100755
--- a/ap/os/linux/linux-3.4.x/mm/mem_tracker.c
+++ b/ap/os/linux/linux-3.4.x/mm/mem_tracker.c
@@ -24,6 +24,8 @@
 /*******************************************************************************
 *                                   ºê¶¨Òå                                     *
 *******************************************************************************/
+#undef CONFIG_KALLSYMS
+
 #ifdef CONFIG_KALLSYMS
 #define MEM_TRACKER_MAX_STACK_LEN  	(100)  /*Õ»º¯Êý¹ì¼£µÄ×Ö·û¸öÊýÉÏÏÞ£»*/
 #endif 
diff --git a/ap/os/linux/linux-3.4.x/mm/slob.c b/ap/os/linux/linux-3.4.x/mm/slob.c
index f26c8d4..0ea5b38 100755
--- a/ap/os/linux/linux-3.4.x/mm/slob.c
+++ b/ap/os/linux/linux-3.4.x/mm/slob.c
@@ -952,7 +952,7 @@
 		slob_list = get_slob_page_list_head(sp);
 
 #ifdef CONFIG_KMALLOC_TRACKER
-		return  (slob_find_general_size(sp) - 2 * sizeof(size_t));
+		return  (slob_find_general_size(sp) - HEAP_SUFFIX_SIZE);
 #endif
 
 #ifdef CONFIG_DEBUG_SLOB_MARK_HEAD
diff --git a/ap/os/linux/linux-3.4.x/net/core/SI/ext_mem.c b/ap/os/linux/linux-3.4.x/net/core/SI/ext_mem.c
index e11b918..1b1d3e4 100755
--- a/ap/os/linux/linux-3.4.x/net/core/SI/ext_mem.c
+++ b/ap/os/linux/linux-3.4.x/net/core/SI/ext_mem.c
@@ -415,7 +415,11 @@
 	bool fastpath;

 

 	//½öÊÊÓÃÓÚÀ´×ÔPSBUFµÄÄÚ´æµÄ¿½±´

-	if(skb->isExtern == 0 && skb->capHead == NULL)

+	if(skb->isExtern == 0 

+#if _USE_VEHICLE_DC

+		&& skb->capHead == NULL

+#endif

+		)

 		return 0;

 	

 	if (skb_shared(skb))

@@ -519,7 +523,9 @@
 	skb->isFastnat= 0;

 	skb->isFastbr= 0;

 	skb->isvlan= 0;

+#if _USE_VEHICLE_DC

 	skb->capHead = NULL;

+#endif

 	atomic_set(&skb_shinfo(skb)->dataref, 1);

 	skbdata_alloc_track(skb);

 	//print_sun(SUN_DBG,"copy  psbuf  to  skbuff !!! \n");

diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
index c3a3a50..7a32a34 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
@@ -417,8 +417,17 @@
 
 extern void net_dbg_perf_dev_recv(char * packet_addr,char* node_str);
 extern void net_dbg_perf_clear_last_item(struct sk_buff *skb);
-
 /* ******************************* º¯ÊýʵÏÖ ******************************* */
+#if _USE_VEHICLE_DC
+static void fast_entry_unlink_cap(fast_entry_t *entry){
+	if(entry->fwd_entry){
+		WARN_ON(entry->fwd_entry->fwd_entry != entry);
+		entry->fwd_entry->fwd_entry = NULL;
+		entry->fwd_entry = NULL;
+	}
+	entry->ct->fast_entry = NULL;
+}
+#endif
 static void fast_bh (unsigned long param)
 {
 	struct sk_buff_head *txq = (struct sk_buff_head *)param;
@@ -608,6 +617,9 @@
     }
 	
 	if (free_entry) {
+#if _USE_VEHICLE_DC
+		cap_conntrack_put(entry->cap_nfct, 1);
+#endif
     	//kfree(entry);
 #ifdef CONFIG_SLOB_OPT
 		kfree(entry);	
@@ -709,6 +721,9 @@
     entry->ct->timeout.function((unsigned long)entry->ct);
     //²»ÔÙÒýÓÃctÁË
     nf_ct_put(entry->ct);
+#if _USE_VEHICLE_DC
+	fast_entry_unlink_cap(entry);
+#endif
     fn_list_del(list_head, entry, free_entry);
 }
 
@@ -2645,7 +2660,44 @@
     rcu_read_unlock();
     return dst;
 }
+#if _USE_VEHICLE_DC
+void fast_update_status_by_capct(void)
+{
+	fast_entry_t *entry, *next;
+	unsigned int pkt0=0,len0=0,pkt1=0,len1=0;
+	void *nfct = NULL;
+	unsigned char in=0, out=0;
 
+	spin_lock_bh(&fastnat_spinlock);
+	for(entry = working_list.next; entry; entry = next)
+	{
+		next = entry->next;
+		if(pkt0 || len0 || pkt1 || len1){
+			cap_conntrack_update(nfct, pkt0, len0, pkt1, len1, in, out);
+			pkt0 = 0;
+			len0 = 0;
+			pkt1 = 0;
+			len1 = 0;
+		}
+		if(entry->cap_nfct && entry->data[0].zvnet_id && entry->data[1].zvnet_id){
+			pkt0 = atomic_read(&entry->data[0].pkt);
+			len0 = atomic_read(&entry->data[0].len);
+			pkt1 = atomic_read(&entry->data[1].pkt);
+			len1 = atomic_read(&entry->data[1].len);
+			nfct = entry->cap_nfct;
+			in = entry->data[1].zvnet_id;
+			out = entry->data[0].zvnet_id;
+			atomic_set(&entry->data[0].pkt, 0);
+			atomic_set(&entry->data[0].len, 0);
+			atomic_set(&entry->data[1].pkt, 0);
+			atomic_set(&entry->data[1].len, 0);
+		}
+	}
+	spin_unlock_bh(&fastnat_spinlock);
+	if(pkt0 || len0 || pkt1 || len1)
+		cap_conntrack_update_end(nfct, pkt0, len0, pkt1, len1, in, out);
+}
+#endif
 /*fast³õʼ»¯*/
 static int __init
 tsp_fast_init(void)
diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fastnat.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fastnat.c
index db8f2e0..21da678 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fastnat.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fastnat.c
@@ -41,6 +41,7 @@
 extern struct sk_buff_head fast_txq;
 extern struct tasklet_struct fast_tx_bh;
 /* **************************** º¯ÊýÉêÃ÷ ************************ */
+extern int zvnet_get_index_by_netdev(struct net_device *net);
 
 
 /* **************************** º¯ÊýʵÏÖ ************************ */
@@ -184,7 +185,8 @@
     u_int32_t skip_nat = 0;
 	struct sk_buff *skb2 = NULL;
 	struct nf_conn_counter *acct = NULL;
-    
+	int zvnet_id = -1;
+
 #if 0//#if !FASTNAT_SUN
     if(!(dev = skb->dev) || !(in_dev = (struct in_device *)(dev->ip_ptr)) || !(in_dev->ifa_list))
     {
@@ -223,7 +225,6 @@
         //print_sun(SUN_DBG, "fast_nat_find  ERR  !!!\n");
         goto err_out;
     }
-
     dev = nat_entry_data->outdev;
     /*¼ì²é°ü³¤¶ÈÊÇ·ñ³¬¹ý³ö¿ÚÉ豸MTU*/
     if (!dev || (skb->len > dev->mtu))
@@ -234,7 +235,7 @@
         //print_sun(SUN_DBG, "fast_nat_recv outdev mtu ERR !!!\n");
         goto err_out;
     }
-    
+
     //»Ø´«µÄ°üÖ±½ÓÊͷŲ¢¼ÆÊý
     if (strcmp(skb->dev->name, dev->name) == 0)
     {
@@ -265,7 +266,271 @@
     }
 
     //tcpdumpin_sq(skb);
-
+#if _USE_VEHICLE_DC
+    zvnet_id = zvnet_get_index_by_netdev(skb->indev);
+	if(nat_entry->fwd_entry){
+		fast_entry_data_t *cap_entry_data = &nat_entry->fwd_entry->data[nat_entry_data->tuplehash.tuple.dst.dir];
+		if(zvnet_id < 0 && cap_entry_data->hh_flag &&
+			(__nf_ct_tuple_src_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple) ||
+			__nf_ct_tuple_dst_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple))){
+			int cap_flag = -1;
+			u_int32_t nat_addr;
+			u_int16_t nat_port;
+			dev = cap_entry_data->outdev;
+			if(!__nf_ct_tuple_src_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple)){
+				cap_flag = 1;
+				nat_addr = cap_entry_data->tuplehash.tuple.src.u3.ip;
+				nat_port = cap_entry_data->tuplehash.tuple.src.u.all;
+			} else if(!__nf_ct_tuple_dst_equal(&cap_entry_data->tuplehash.tuple, &nat_entry_data->tuplehash.tuple)){
+				cap_flag = 0;
+				nat_addr = cap_entry_data->tuplehash.tuple.dst.u3.ip;
+				nat_port = cap_entry_data->tuplehash.tuple.dst.u.all;
+			}
+			if (!(skb2 = fast_expand_headroom(skb, dev))){
+				rcu_read_unlock();
+				return 1;
+			}
+			if(skb2 != skb){
+				iph = (struct iphdr *)skb2->data;
+				skb = skb2;
+			}
+			fast_tcpdump(skb);
+			//Èç¹û×¥°üÃüÖУ¬Êý¾Ý»áclone£¬fast³É¹¦ÐèÒª¸Ä±ädataÄÚÈÝ£¬ÐèÒªÖØÐÂcopyÒ»·Ý
+			if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)){
+				rcu_read_unlock();
+				printk("pskb_expand_head0 skb failed, free skb\n");
+				kfree_skb(skb);
+				return 1;
+			}
+			
+			/*½øÐжª°ü¸ú×Ù*/
+			if(IPPROTO_TCP == iph->protocol)
+				packet_lost_track(skb, nat_entry->ct);
+			skb_reset_network_header(skb);
+			skb->isFastnat = 1;
+			if (cap_flag >= 0){
+				if (IPPROTO_TCP == iph->protocol){
+					tcph = (struct tcphdr *)(skb->data + iph->ihl * 4);
+					cksum = &tcph->check;
+					oldport = cap_flag ? (&tcph->source): (&tcph->dest);
+				}
+				else if (IPPROTO_UDP == iph->protocol){
+					udph = (struct udphdr *)(skb->data + iph->ihl * 4);
+					cksum = &udph->check;
+					oldport = cap_flag ? (&udph->source): (&udph->dest);
+				}
+				oldip = cap_flag? (&iph->saddr) : (&iph->daddr);
+				if (cksum != NULL && (0!=*cksum || IPPROTO_TCP == iph->protocol)){
+					inet_proto_csum_replace4(cksum, skb, *oldip, nat_addr, 0);
+					inet_proto_csum_replace2(cksum, skb, *oldport, nat_port, 0);
+				}
+				csum_replace4(&iph->check, *oldip, nat_addr);
+				if(oldport)
+				*oldport = nat_port;
+				*oldip = nat_addr;
+			}
+			else
+			{
+				if (IPPROTO_TCP == iph->protocol)
+				{
+					tcph = (struct tcphdr *)(skb->data + iph->ihl * 4);
+				}
+			}
+			skb->priority = cap_entry_data->priority;
+			skb->mark = cap_entry_data->mark;
+			if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL){
+				nat_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].packets++;
+				nat_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].bytes += skb->len;
+				nat_entry->fwd_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].packets++;
+				nat_entry->fwd_entry->ct->packet_info[IP_CT_DIR_ORIGINAL].bytes += skb->len;
+			} else if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_REPLY){
+				nat_entry->ct->packet_info[IP_CT_DIR_REPLY].packets++;
+				nat_entry->ct->packet_info[IP_CT_DIR_REPLY].bytes += skb->len;
+				nat_entry->fwd_entry->ct->packet_info[IP_CT_DIR_REPLY].packets++;
+				nat_entry->fwd_entry->ct->packet_info[IP_CT_DIR_REPLY].bytes += skb->len;
+			} else {
+				printk("fastnat packet error\n");
+			}
+			{
+				enum ip_conntrack_info ctinfo;
+				if (nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL)
+					ctinfo = IP_CT_ESTABLISHED;
+				else 
+					ctinfo = IP_CT_ESTABLISHED_REPLY;
+				acct = nf_conn_acct_find(nat_entry->ct);
+				if (acct) {
+					atomic64_inc(&acct[CTINFO2DIR(ctinfo)].packets);
+					atomic64_add(skb->len, &acct[CTINFO2DIR(ctinfo)].bytes);
+				}
+				acct = nf_conn_acct_find(nat_entry->fwd_entry->ct);
+				if (acct) {
+					atomic64_inc(&acct[CTINFO2DIR(ctinfo)].packets);
+					atomic64_add(skb->len, &acct[CTINFO2DIR(ctinfo)].bytes);
+				}
+				atomic_inc(&nat_entry_data->pkt);
+				atomic_add(skb->len, &nat_entry_data->len);
+				if(atomic_read(&nat_entry_data->len) > 1000000){
+					cap_conntrack_update_end(nat_entry->cap_nfct,
+						atomic_read(&nat_entry->data[0].pkt),atomic_read(&nat_entry->data[0].len),
+						atomic_read(&nat_entry->data[1].pkt),atomic_read(&nat_entry->data[1].len),
+						nat_entry->data[1].zvnet_id,nat_entry->data[0].zvnet_id);
+						spin_lock_bh(&fastnat_spinlock);
+						atomic_set(&nat_entry->data[0].pkt, 0);
+						atomic_set(&nat_entry->data[0].len, 0);
+						atomic_set(&nat_entry->data[1].pkt, 0);
+						atomic_set(&nat_entry->data[1].len, 0);
+						spin_unlock_bh(&fastnat_spinlock);
+				}
+			}
+			if (fastnat_level == FAST_NET_DEVICE){
+				if (nat_entry_data->indev){
+					nat_entry_data->indev->stats.rx_packets++;
+					nat_entry_data->indev->stats.rx_bytes += skb->len;
+				}
+				if (cap_entry_data->indev){
+					cap_entry_data->indev->stats.rx_packets++;
+					cap_entry_data->indev->stats.rx_bytes += skb->len;
+				}
+				if(skb->indev && nat_entry_data->indev != skb->indev && cap_entry_data->indev != skb->indev ){
+					skb->indev->stats.rx_packets++;
+					skb->indev->stats.rx_bytes += skb->len;
+				}
+			}
+			skb->dev = dev;
+			skb_push(skb, ETH_HLEN);
+			//if (cap_entry_data->hh_flag)
+			memcpy(skb->data, cap_entry_data->hh_data, ETH_HLEN);
+			/*¸üÐÂÁ´½Ó³¬Ê±*/
+			if (IPPROTO_TCP == iph->protocol){
+				mod_timer(&nat_entry->timeout, jiffies + tcp_timeouts[nat_entry->ct->proto.tcp.state]);
+				mod_timer(&nat_entry->fwd_entry->timeout, jiffies + tcp_timeouts[nat_entry->fwd_entry->ct->proto.tcp.state]);
+				update_tcp_timeout(nat_entry, nat_entry_data, tcph);
+				update_tcp_timeout(nat_entry->fwd_entry, cap_entry_data, tcph);
+		 
+				if(ackfilter(skb, nat_entry, &working_list) == 1 || ackfilter(skb, nat_entry->fwd_entry, &working_list) == 1){
+					rcu_read_unlock();
+					//spin_unlock_bh(&fastnat_spinlock);
+					return 1;
+				}
+			}
+			else if (IPPROTO_UDP == iph->protocol){
+				/*udp*/
+				if (fast_test_bit(IPS_SEEN_REPLY_BIT, nat_entry->ct->status)){
+					mod_timer(&nat_entry->timeout, jiffies + fast_udp_timeout_stream);
+					mod_timer(&nat_entry->fwd_entry->timeout, jiffies + fast_udp_timeout_stream);
+				}else{
+					mod_timer(&nat_entry->timeout, jiffies + fast_udp_timeout);
+					mod_timer(&nat_entry->fwd_entry->timeout, jiffies + fast_udp_timeout);
+				}
+			}
+			if (skb->dev->flags & IFF_UP){
+				if (skb->dev->type == ARPHRD_PPP || skb->dev->type == ARPHRD_NONE)
+					skb_pull(skb, ETH_HLEN);
+				skb->now_location |= FASTNAT_SUCC;
+				if(unlikely(skb->dev->type == ARPHRD_NONE)){
+					struct ipv6hdr header = {0};
+					const struct iphdr *old_header = (struct iphdr *)skb->data;
+					unsigned int len = skb->len;
+					int rc = -ENOMEM;
+				
+					header.version = 6;
+					header.payload_len = htons(ntohs(old_header->tot_len) - sizeof(struct iphdr));
+					header.nexthdr = old_header->protocol;
+					header.hop_limit = old_header->ttl;
+					header.saddr = g_ipv6_local_subnet;
+					header.daddr = g_plat_subnet;
+					header.daddr.s6_addr32[3] = old_header->daddr;
+					skb_push(skb, sizeof(struct ipv6hdr) - sizeof(struct iphdr));
+					memcpy(skb->data, &header, sizeof(struct ipv6hdr));
+					if (!(skb2 = fast_expand_headroom(skb, g_xlat_dev))){
+						rcu_read_unlock();
+						return 1;
+					}
+					if(skb2 != skb)
+						skb = skb2;
+					skb_push(skb, ETH_HLEN);
+					skb->dev = g_xlat_dev;
+				}
+				if (fastnat_level == FAST_NET_DEVICE){
+					if(speedMode == 0)
+						dev_queue_xmit(skb);
+					else if(skb->dev->netdev_ops && skb->dev->netdev_ops->ndo_start_xmit
+						&& skb->dev->netdev_ops->ndo_select_queue == NULL  
+						&& (skb->dev->type != ARPHRD_PPP)){
+						int rc = -ENOMEM;
+						rc = skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev);
+						if (!dev_xmit_complete(rc)) {
+							skb->dev->stats_dbg.tx_dropped++;
+							skb->dev->stats.tx_dropped++;
+							skbinfo_add(NULL,SKB_ERRFREE);
+							kfree_skb(skb);
+						}
+					}
+					else if(skb->dev->type == ARPHRD_PPP){
+						skb_queue_tail(&fast_txq, skb);
+						tasklet_schedule(&fast_tx_bh);
+					}
+					else
+						dev_queue_xmit(skb);
+				}
+				else if (fastnat_level == FAST_NET_CORE)
+					dev_queue_xmit(skb);
+				nat_entry_data->packet_num++;
+				cap_entry_data->packet_num++;
+			}
+			else
+				kfree_skb(skb);
+			rcu_read_unlock();
+			return 1;
+		}
+	}else{
+		if(unlikely(fastbr_level != 1)){
+			if(skb->nfct_bak && skb->capNfct){
+				struct nf_conn *ct_fwd = (struct nf_conn *)skb->nfct_bak;
+				if (ct_fwd->fast_entry){
+					fast_entry_t *nat_entry_fwd = (fast_entry_t *)ct_fwd->fast_entry;
+					if (nat_entry_fwd){
+						/*skbÒѾ­ÈÆ»ØÀ´ÁË£¬°ó¶¨ÐÂÀÏfast£¬¼Ç¼capct*/
+						spin_lock_bh(&fastnat_spinlock);
+						nat_entry_fwd->fwd_entry = nat_entry;
+						nat_entry_fwd->cap_nfct = skb->capNfct;
+						nat_entry->fwd_entry = nat_entry_fwd;
+						nat_entry->cap_nfct = skb->capNfct;
+						atomic_set(&nat_entry->data[0].pkt, 0);
+						atomic_set(&nat_entry->data[0].len, 0);
+						atomic_set(&nat_entry->data[1].pkt, 0);
+						atomic_set(&nat_entry->data[1].len, 0);
+						atomic_set(&nat_entry_fwd->data[0].pkt, 0);
+						atomic_set(&nat_entry_fwd->data[0].len, 0);
+						atomic_set(&nat_entry_fwd->data[1].pkt, 0);
+						atomic_set(&nat_entry_fwd->data[1].len, 0);
+						spin_unlock_bh(&fastnat_spinlock);
+						skb->capNfct = NULL;
+						if(zvnet_id >= 0 && nat_entry_data->zvnet_id == 0){
+							nat_entry_data->zvnet_id = zvnet_id+1;
+							if(nat_entry_data->tuplehash.tuple.dst.dir == IP_CT_DIR_ORIGINAL){
+								nat_entry->data[IP_CT_DIR_REPLY].zvnet_id = skb->zvnet_id;
+								nat_entry_fwd->data[IP_CT_DIR_ORIGINAL].zvnet_id = nat_entry->data[IP_CT_DIR_ORIGINAL].zvnet_id;
+								nat_entry_fwd->data[IP_CT_DIR_REPLY].zvnet_id = nat_entry->data[IP_CT_DIR_REPLY].zvnet_id;
+							}else{
+								nat_entry->data[IP_CT_DIR_ORIGINAL].zvnet_id = skb->zvnet_id;
+								nat_entry_fwd->data[IP_CT_DIR_ORIGINAL].zvnet_id = nat_entry->data[IP_CT_DIR_ORIGINAL].zvnet_id;
+								nat_entry_fwd->data[IP_CT_DIR_REPLY].zvnet_id = nat_entry->data[IP_CT_DIR_REPLY].zvnet_id;
+							}
+						}
+					}
+				}
+			}
+			if(zvnet_id < 0){
+				/*·¢¸øzvnetµÄÊý¾Ý£¬×ßµ½fast£¬¼Ç¼ctºÍfast°ó¶¨*/
+				nf_conntrack_put(skb->nfct);
+				skb->nfct = &nat_entry->ct->ct_general;
+				nf_conntrack_get(skb->nfct);
+				nat_entry->ct->fast_entry = nat_entry;
+			}
+		}
+	}
+#endif
     if (!(skb2 = fast_expand_headroom(skb, dev))){
         rcu_read_unlock();
         return 1;
@@ -399,11 +664,20 @@
 
     //Ö»Óе±ÓÐMACÍ·Ô¤¸³ÖµÊ±£¬²Å×¼¸³Öµ£¬·ñÔòΪIPÍ·
     skb_push(skb, ETH_HLEN);
-    if (nat_entry_data->hh_flag)
+    if (nat_entry_data->hh_flag == 1)
     {
         memcpy(skb->data, nat_entry_data->hh_data, ETH_HLEN);
     }
-
+#if _USE_VEHICLE_DC
+	else{
+		if (fastbr_level != 1 && zvnet_id >= 0 && nat_entry_data->hh_flag == 0){
+			spin_lock_bh(&fastnat_spinlock);
+			memcpy(nat_entry_data->hh_data, skb->data, ETH_HLEN);
+			nat_entry_data->hh_flag = 2;
+			spin_unlock_bh(&fastnat_spinlock);
+		}
+	}
+#endif
 #if 0
     if(!(dev->flags & IFF_POINTOPOINT))
     {
@@ -455,7 +729,7 @@
         }
         
         skb->now_location |= FASTNAT_SUCC;
-		
+
 		if(unlikely(skb->dev->type == ARPHRD_NONE)){
 			struct ipv6hdr header = {0};
 			const struct iphdr *old_header = (struct iphdr *)skb->data;
diff --git a/ap/os/linux/linux-3.4.x/net/core/skbuff.c b/ap/os/linux/linux-3.4.x/net/core/skbuff.c
index 6aaf23e..1f6f05f 100755
--- a/ap/os/linux/linux-3.4.x/net/core/skbuff.c
+++ b/ap/os/linux/linux-3.4.x/net/core/skbuff.c
@@ -634,6 +634,10 @@
 	}
 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
 	nf_conntrack_put(skb->nfct);
+#if _USE_VEHICLE_DC
+	nf_conntrack_put(skb->nfct_bak);
+	cap_conntrack_put(skb->capNfct,2);
+#endif
 #endif
 #ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
 	nf_conntrack_put_reasm(skb->nfct_reasm);
@@ -842,7 +846,12 @@
 	C(truesize);
 	
 	//¶ÔÓÚdataµÄÐÂÔöÊôÐÔ£¬skb¿½±´Ê±Òª¼Ì³Ð£¬ÒòΪÁ½¸öskbÖ¸ÏòµÄÊÇͬһ¸ödataÇøÓò
+#if _USE_VEHICLE_DC
 	C(capHead);
+	n->nfct_bak = NULL;
+	n->capNfct = NULL;
+	n->zvnet_id = 0;
+#endif
 	C(isExtern);
 	C(isFastbr);
 	C(isFastnat);
@@ -1166,9 +1175,17 @@
 		fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta;
 	}
 #ifndef CONFIG_SPEED_OPT
-	if (fastpath && skb->isExtern==0 && skb->capHead == NULL && size + sizeof(struct skb_shared_info) <= ksize(skb->head)) 
+	if (fastpath && skb->isExtern==0 
+#if _USE_VEHICLE_DC
+	&& skb->capHead == NULL 
+#endif
+	&& size + sizeof(struct skb_shared_info) <= ksize(skb->head)) 
 #else
-	if (fastpath && skb->isExtern==0 && skb->capHead == NULL && size + sizeof(struct skb_shared_info) <= skb_sys_pool_size(skb->head)) 
+	if (fastpath && skb->isExtern==0 
+#if _USE_VEHICLE_DC
+	&& skb->capHead == NULL 
+#endif
+	&& size + sizeof(struct skb_shared_info) <= skb_sys_pool_size(skb->head)) 
 #endif
 	{	memmove(skb->head + size, skb_shinfo(skb),
 			offsetof(struct skb_shared_info,
@@ -1202,7 +1219,11 @@
 	       skb_shinfo(skb),
 	       offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags]));
 
-	if (fastpath && skb->capHead == NULL) {
+	if (fastpath 
+#if _USE_VEHICLE_DC
+		&& skb->capHead == NULL
+#endif
+		) {
 		{
 			if(skb->isExtern == 1)
 			{
@@ -1255,7 +1276,9 @@
 	skb->cloned   = 0;
 	skb->hdr_len  = 0;
 	skb->nohdr    = 0;
+#if _USE_VEHICLE_DC
 	skb->capHead = NULL;
+#endif
 	skb->isExtern = 0;
 	skb->isFastnat= 0;
 	skb->isFastbr= 0;
diff --git a/ap/os/linux/linux-3.4.x/net/netfilter/nf_conntrack_core.c b/ap/os/linux/linux-3.4.x/net/netfilter/nf_conntrack_core.c
old mode 100644
new mode 100755
index 11af7a7..537e072
--- a/ap/os/linux/linux-3.4.x/net/netfilter/nf_conntrack_core.c
+++ b/ap/os/linux/linux-3.4.x/net/netfilter/nf_conntrack_core.c
@@ -905,7 +905,7 @@
 #ifdef CONFIG_TSP_FASTBIH
 	ct->isbih = 0;
 #endif
-
+	ct->fast_entry = NULL;
 	return &ct->tuplehash[IP_CT_DIR_ORIGINAL];
 }