[Feature][ZXW-237]merge P54U03 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: Id39ef8b992af691eab09c01d4ea26da89e5f4049
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/include/asm/unistd.h b/ap/os/linux/linux-3.4.x/arch/arm/include/asm/unistd.h
index 73e3fdd..77dae2a 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/include/asm/unistd.h
+++ b/ap/os/linux/linux-3.4.x/arch/arm/include/asm/unistd.h
@@ -418,7 +418,7 @@
#define __NR_vsim_read (__NR_SYSCALL_BASE+389)
#define __NR_vsim_write (__NR_SYSCALL_BASE+390)
#define __NR_vsim_proc (__NR_SYSCALL_BASE+391)
-
+#define __NR_set_xlat (__NR_SYSCALL_BASE+392)
/*
* The following SWIs are ARM private.
*/
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/kernel/calls.S b/ap/os/linux/linux-3.4.x/arch/arm/kernel/calls.S
index 3d64325..a5fbba4 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/kernel/calls.S
+++ b/ap/os/linux/linux-3.4.x/arch/arm/kernel/calls.S
@@ -401,6 +401,7 @@
CALL(sys_vsim_read)
CALL(sys_vsim_write)
CALL(sys_vsim_proc)
+ CALL(sys_set_xlat)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/board-zx297520v3.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/board-zx297520v3.c
index c15a4ef..929e125 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/board-zx297520v3.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/board-zx297520v3.c
@@ -526,6 +526,21 @@
return 0;
}
+typedef int (*set_xlat_CB)(unsigned char *ip_info, unsigned char *dev_name);
+set_xlat_CB g_set_xlat_cb = NULL;
+SYSCALL_DEFINE2(set_xlat, char __user *, ip_info, char __user *, dev_name)
+{
+ unsigned char info[40] = {0};
+ unsigned char dev[16] = {0};
+ if(g_set_xlat_cb != NULL){
+ if(copy_from_user(&info, ip_info, sizeof(info)) == 0
+ && copy_from_user(&dev, dev_name, sizeof(dev)) == 0 ){
+ return g_set_xlat_cb(&info, &dev);
+ }
+ }
+ return 0;
+}
+
#if 0
SYSCALL_DEFINE5(get_devinfo, struct lcd_info __user *, lcd_dev,
struct wifi_info __user *, wifi_dev,
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 c6a0602..cced966 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=(0x12ad+3367-0x1fd4);if(!user_mode(regs)){preempt_disable();if(
-kprobe_running()&&kprobe_fault_handler(regs,fsr))ret=(0x12cf+1682-0x1960);
-preempt_enable();}return ret;}
+ret=(0x93f+4978-0x1cb1);if(!user_mode(regs)){preempt_disable();if(kprobe_running
+()&&kprobe_fault_handler(regs,fsr))ret=(0x7d1+6843-0x228b);preempt_enable();}
+return ret;}
#else
static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){return
-(0x1bf2+2048-0x23f2);}
+(0x19fd+1761-0x20de);}
#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!=(0x824+35-0x846))printk(
+pgd,addr);if(PTRS_PER_PUD!=(0x82a+6948-0x234d))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!=(0x364+38-0x389))printk(
+}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0xe5c+2467-0x17fe))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,21 +47,21 @@
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((0x272+8475-0x238d));printk("\n");}
+pte_unmap(pte);}while((0x15a5+631-0x181c));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(
-(0x1545+4125-0x2561));printk(KERN_ALERT
+(0x4c3+8549-0x2627));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((0xc84+590-0xed2));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;
+addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0x497+3142-0x10dd));
+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;
#ifdef CONFIG_DEBUG_USER
if(((user_debug&UDBG_SEGV)&&(sig==SIGSEGV))||((user_debug&UDBG_BUS)&&(sig==
SIGBUS))){printk(KERN_DEBUG
@@ -69,12 +69,12 @@
,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=
-(0x1100+1036-0x14fe);si.si_signo=sig;si.si_errno=(0x1804+3286-0x24da);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(tsk,addr,fsr,SIGSEGV,SEGV_MAPERR,regs);else __do_kernel_fault(mm
-,addr,fsr,regs);}
+(0x38d+3694-0x11ed);si.si_signo=sig;si.si_errno=(0x1832+3224-0x24ca);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(
+tsk,addr,fsr,SIGSEGV,SEGV_MAPERR,regs);else __do_kernel_fault(mm,addr,fsr,regs);
+}
#ifdef CONFIG_MMU
#define VM_FAULT_BADMAP 65536
#define VM_FAULT_BADACCESS 131072
@@ -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:(0x6c0+4256-0x1760));if(
-notify_page_fault(regs,fsr))return(0xdeb+2245-0x16b0);tsk=current;mm=tsk->mm;if(
+FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0xcfc+4929-0x203d));if(
+notify_page_fault(regs,fsr))return(0xe67+6073-0x2620);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(0xba1+1906-0x1313);perf_sw_event(
-PERF_COUNT_SW_PAGE_FAULTS,(0x187+8029-0x20e3),regs,addr);if(!(fault&
+fatal_signal_pending(current))return(0x1108+1641-0x1771);perf_sw_event(
+PERF_COUNT_SW_PAGE_FAULTS,(0x159d+3344-0x22ac),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,(0x741+2004-0xf14),regs,
+maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0xc0a+6112-0x23e9),regs,
addr);}else{tsk->min_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
-(0xd8b+267-0xe95),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
+(0x1ea0+1997-0x266c),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(0x130f+2815-0x1e0e);
-if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0x317+4165-0x135c);}if(!
+VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x322+877-0x68f);if(
+fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0xc0b+3332-0x190f);}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
-(0xe18+1192-0x12c0);no_context:__do_kernel_fault(mm,addr,fsr,regs);return
-(0x1393+593-0x15e4);}
+SEGV_MAPERR;}__do_user_fault(tsk,addr,fsr,sig,code,regs);return(0x826+883-0xb99)
+;no_context:__do_kernel_fault(mm,addr,fsr,regs);return(0xb25+4796-0x1de1);}
#else
static int do_page_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
-){return(0x1f8+6958-0x1d26);}
+){return(0x2f0+2220-0xb9c);}
#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=(0xce3+5951-0x2422);
+index=(0xef9+3662-0x1d47);
#else
-index=(addr>>SECTION_SHIFT)&(0xe8a+4619-0x2094);
+index=(addr>>SECTION_SHIFT)&(0x214f+1030-0x2554);
#endif
if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0x115+9321-0x257e);bad_area:do_bad_area(addr,fsr,regs);return
-(0x494+8636-0x2650);}
+(0x1ba7+2731-0x2652);bad_area:do_bad_area(addr,fsr,regs);return
+(0x802+3502-0x15b0);}
#else
static int do_translation_fault(unsigned long addr,unsigned int fsr,struct
-pt_regs*regs){return(0xe3b+3297-0x1b1c);}
+pt_regs*regs){return(0xad2+644-0xd56);}
#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(0x8e3+6172-0x20ff);}static int do_bad(unsigned long addr,unsigned int fsr
-,struct pt_regs*regs){return(0x173a+1692-0x1dd5);}struct fsr_info{int(*fn)(
+return(0x12c7+3422-0x2025);}static int do_bad(unsigned long addr,unsigned int
+fsr,struct pt_regs*regs){return(0x157d+1947-0x1d17);}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<(0xc0a+725-0xedf)||nr>=
+pt_regs*),int sig,int code,const char*name){if(nr<(0xe90+4895-0x21af)||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(
-(0x439+4334-0x1527));struct addr_info{struct list_head node;unsigned long vaddr;
+(0x9ad+1603-0xff0));struct addr_info{struct list_head node;unsigned long vaddr;
unsigned long kaddr;unsigned long page_index;};enum modem_access_technology{GSM=
-(0x13e8+346-0x1542),UTRAN=(0xdb5+5486-0x2322),LTE=(0x370+7689-0x2177),COM=
-(0x12c8+4192-0x2325),NR_MODEM_ACCESS=(0x3ab+1812-0xabb)};struct list_head
+(0x140+9320-0x25a8),UTRAN=(0x173b+3236-0x23de),LTE=(0x175f+3613-0x257a),COM=
+(0x1155+3868-0x206e),NR_MODEM_ACCESS=(0x375+5265-0x1802)};struct list_head
modem_page_list[NR_MODEM_ACCESS]={LIST_HEAD_INIT(modem_page_list[
-(0xc2+7787-0x1f2d)]),LIST_HEAD_INIT(modem_page_list[(0x13e2+4770-0x2683)]),
-LIST_HEAD_INIT(modem_page_list[(0x564+4401-0x1693)]),LIST_HEAD_INIT(
-modem_page_list[(0x199+2282-0xa80)]),};unsigned int page_used[
-(0x1390+4072-0x2350)];struct completion page_completion[(0x88d+6027-0x1ff0)*
-(0x15b2+252-0x168e)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
+(0xfc0+179-0x1073)]),LIST_HEAD_INIT(modem_page_list[(0x213c+714-0x2405)]),
+LIST_HEAD_INIT(modem_page_list[(0x1f2a+681-0x21d1)]),LIST_HEAD_INIT(
+modem_page_list[(0x1ca0+165-0x1d42)]),};unsigned int page_used[
+(0x1091+3756-0x1f15)];struct completion page_completion[(0x1e62+726-0x2110)*
+(0x22bd+799-0x25bc)];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=(0x696+4084-0x168a);unsigned
+shrink_modem_mem(unsigned int access_type){int i=(0x650+7924-0x2544);unsigned
long vaddr;struct addr_info*addr,*tmp_addr;struct list_head tmp_page_list;for(i=
-(0xf+934-0x3b5);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){
+(0x776+6013-0x1ef3);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=
-(0x173f+3119-0x236e);page_used[addr->page_index/BITS_PER_LONG]&=~(
-(0x1d3+6472-0x1b1a)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
+(0x126b+4818-0x253d);page_used[addr->page_index/BITS_PER_LONG]&=~(
+(0x174+1177-0x60c)<<(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,14 +195,14 @@
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,
-(0xadf+892-0xe5a));local_irq_restore(flags);
+(0x1254+2865-0x1d84));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(0xa62+3255-0x1719);}static int sync_pgd(unsigned long addr,
+pfn);}}}return(0x158b+2513-0x1f5c);}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))
@@ -211,38 +210,37 @@
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=(0x1dd0+1484-0x239c);
+index=(0x1c66+637-0x1ee3);
#else
-index=(addr>>SECTION_SHIFT)&(0x3ba+3661-0x1206);
+index=(addr>>SECTION_SHIFT)&(0x3cb+932-0x76e);
#endif
if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0x8b1+6087-0x2078);bad_area:do_bad_area(addr,fsr,regs);return
-(0xd2d+3946-0x1c97);}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(
+(0x1c0+1357-0x70d);bad_area:do_bad_area(addr,fsr,regs);return(0x732+2365-0x106f)
+;}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<(0xf9+502-0x2ef)){panic(
+char*)code_buf,PAGE_SIZE,&pos);if(result<(0x473+2894-0xfc1)){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,
-(0x999+3702-0x180e));local_irq_restore(flags);
+(0x1653+299-0x177d));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)!=(0x5c6+5202-0x1a18)
+unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=(0x271+4686-0x14bf)
){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)&
-(0x871+1586-0xea2)){wait_for_completion(&page_completion[page_index]);sync_pgd(
+(0x16d9+964-0x1a9c)){wait_for_completion(&page_completion[page_index]);sync_pgd(
vaddr,fsr,regs);return;}else page_used[page_index/BITS_PER_LONG]|=(
-(0x4dc+1329-0xa0c)<<page_shift);local_irq_enable();vir_codebuf=read_code_file(
+(0x8eb+2380-0x1236)<<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.
@@ -260,46 +258,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!=(0xb54+2091-0x137f)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x16cd+2408-0x2035)&&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=(0x12fb+4902-0x2621);
+,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0x1942+1864-0x208a);
info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,fsr,(0x45b+1782-0xb51));}void __init hook_ifault_code(int nr,int(*fn)(
+info,fsr,(0x1069+4485-0x21ee));}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<(0x188d+151-0x1924)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
+(nr<(0xb51+5748-0x21c5)||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!=(0x13b1+565-0x15e6)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x16b6+333-0x1803)&&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=(0xd47+4901-0x206c);
+,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x466+4584-0x164e);
info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,ifsr,(0xfb2+3290-0x1c8c));}
+info,ifsr,(0xbac+5846-0x2282));}
#ifndef CONFIG_ARM_LPAE
static int __init exceptions_init(void){if(cpu_architecture()>=CPU_ARCH_ARMv6){
-hook_fault_code((0x654+6496-0x1fb0),do_translation_fault,SIGSEGV,SEGV_MAPERR,
+hook_fault_code((0x9c9+4338-0x1ab7),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((0x643+2473-0xfe9),
+);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0x169c+2480-0x2049),
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((0x10f9+3556-0x1ed7),do_bad,SIGSEGV,SEGV_MAPERR,
+);hook_fault_code((0x908+417-0xaa3),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=(0xb70+6003-0x22e3);for(index=(0x67c+2578-0x108e);index<
-(0x154d+97-0x1586)*(0xf56+2316-0x1842);index++)init_completion(&page_completion[
-index]);
+int index=(0xc6b+4048-0x1c3b);for(index=(0x713+2892-0x125f);index<
+(0x36f+5900-0x1a53)*(0x10d9+4448-0x2219);index++)init_completion(&
+page_completion[index]);
#endif
-return(0x332+635-0x5ad);}arch_initcall(exceptions_init);
+return(0x18ab+1624-0x1f03);}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 5a45243..7a9c22c 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
@@ -83,30 +83,30 @@
unsigned int __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(0x316+6712-0x1d4e);}extern unsigned int SysEntry(void);static int
+return(0x404+8970-0x270e);}extern unsigned int SysEntry(void);static int
ko_Main_Thread(void*data){struct sched_param param={.sched_priority=
-MAX_USER_RT_PRIO/(0xe6b+2120-0x16b1)-(0x1975+1578-0x1f9c)};int ret=
-(0x3a0+6131-0x1b93);sched_setscheduler(current,SCHED_FIFO,¶m);ret=SysEntry()
-;if(ret!=(0x1419+3950-0x2387))panic("Main_Thread\n");param.sched_priority=
-MAX_USER_RT_PRIO-(0x10ed+82-0x1111);sched_setscheduler(kthreadd_task,SCHED_FIFO,
-¶m);return(0x227+8075-0x21b2);}int zte_modem_ko_start(void){kthread_run(
+MAX_USER_RT_PRIO/(0xafb+4511-0x1c98)-(0x1633+3815-0x2517)};int ret=
+(0x1f43+402-0x20d5);sched_setscheduler(current,SCHED_FIFO,¶m);ret=SysEntry()
+;if(ret!=(0x10b8+3966-0x2036))panic("Main_Thread\n");param.sched_priority=
+MAX_USER_RT_PRIO-(0xfb3+2852-0x1aa9);sched_setscheduler(kthreadd_task,SCHED_FIFO
+,¶m);return(0xaa6+6401-0x23a7);}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(0x890+7748-0x26d4);}static void cpko_sectioninfo_set(void){int ret;struct
- file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x1570+4436-0x26c4);struct
+return(0x8b9+1955-0x105c);}static void cpko_sectioninfo_set(void){int ret;struct
+ file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x6ed+5503-0x1c6c);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"
-,(0x294+1512-0x87c),(0xe06+3271-0x1acd));if(IS_ERR(fp)||fp==NULL)panic(
+,(0xf28+2571-0x1933),(0xa59+1171-0xeec));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<=(0x3ca+7257-0x2023))panic(
+cpko_section_layout),&cpko_pos);if(ret<=(0x304+3756-0x11b0))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",
-(0x9ca+4617-0x1bd3),(0x659+7219-0x228c));if(IS_ERR(fp)||fp==NULL)panic(
+(0x1019+4563-0x21ec),(0x1cf2+1837-0x241f));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=(0xac6+6080-0x2286);
+ra_pages=(0x53f+4485-0x16c4);
#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)
@@ -126,7 +126,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={(0x5b7+4236-0x1643)};callback.
+cpko_start(void){struct cpps_callbacks callback={(0x913+4588-0x1aff)};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.
@@ -198,5 +198,5 @@
psm_GetModemSleepFlagStatus=psm_GetModemSleepFlagStatus;
#endif
cpps_callbacks_register(&callback);cpko_sectioninfo_set();zte_modem_ko_start();
-return(0x1997+168-0x1a3f);}static int cpko_stop(void){return(0x636+5784-0x1cce);
+return(0xb43+4520-0x1ceb);}static int cpko_stop(void){return(0x20cd+460-0x2299);
}module_init(cpko_start);module_exit(cpko_stop);
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/psnet/psnet_dev.c b/ap/os/linux/linux-3.4.x/drivers/net/psnet/psnet_dev.c
index 5df877d..09a1b2b 100755
--- a/ap/os/linux/linux-3.4.x/drivers/net/psnet/psnet_dev.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/psnet/psnet_dev.c
@@ -6,6 +6,14 @@
#include "psnet.h"
#include "psnet_io.h"
#include <mach/iomap.h>
+
+#include <linux/if_addr.h>
+#include <linux/ip.h>
+#include <net/ip.h>
+#include <linux/ipv6.h>
+#include <net/ipv6.h>
+#include <net/protocol.h>
+
#define WATCHDOG_TIMEO (5*HZ)
/* NET NUMBER; channel id; lan/wan*/
@@ -248,6 +256,49 @@
netif_wake_queue(net);
}
+typedef int (*set_xlat_CB)(unsigned char *ip_info, unsigned char *dev_name);
+extern set_xlat_CB g_set_xlat_cb;
+extern struct in6_addr g_plat_subnet;
+extern struct in6_addr g_ipv6_local_subnet;
+extern struct in_addr g_ipv4_local_subnet;
+extern struct net_device *g_xlat_dev;
+int psnet_set_xlat(unsigned char *ip_info, unsigned char *dev_name)
+{
+ unsigned char *buff = ip_info;
+ memcpy(&g_plat_subnet, buff, sizeof(struct in6_addr));
+ buff = buff + sizeof(struct in6_addr);
+ memcpy(&g_ipv6_local_subnet, buff, sizeof(struct in6_addr));
+ buff = buff + sizeof(struct in6_addr);
+ memcpy(&g_ipv4_local_subnet, buff, sizeof(struct in_addr));
+ g_xlat_dev = dev_get_by_name(&init_net, dev_name);
+}
+
+int fill_ip_header(struct iphdr *ip, const struct ipv6hdr *old_header) {
+ if(memcmp(&old_header->saddr, &g_plat_subnet, 12)){
+ return 0;
+ }
+ if(memcmp(&old_header->daddr, &g_ipv6_local_subnet, 16)){
+ return 0;
+ }
+ ip->saddr = old_header->saddr.s6_addr32[3];
+ ip->daddr = g_ipv4_local_subnet.s_addr;
+ ip->ihl = 5;
+ ip->version = 4;
+ ip->tos = 0;
+ ip->tot_len = htons(sizeof(struct iphdr) + ntohs(old_header->payload_len));
+ ip->id = 0;
+ ip->frag_off = htons(IP_DF);
+ ip->ttl = old_header->hop_limit;
+ ip->protocol = old_header->nexthdr;
+ ip->check = 0;
+ return 1;
+}
+extern int fast_nat_check(unsigned char *data);
+extern uint32_t ipv6_pseudo_header_checksum(const struct ipv6hdr *ip6, uint16_t len, uint8_t protocol);
+extern uint32_t ipv4_pseudo_header_checksum(const struct iphdr *ip, uint16_t len);
+extern uint16_t ip_checksum(const void *data, int len);
+extern uint16_t ip_checksum_adjust(uint16_t checksum, uint32_t old_hdr_sum, uint32_t new_hdr_sum);
+
#define PSBUFF_DL_HEADER_OFFSET 64 //80
//extern void * zGetpsbufferHead(void * data);
void psnet_recv_notify(unsigned int index, const void *buffer, unsigned int length)//(T_ZDrvRpMsg_Msg rpmsg)
@@ -267,6 +318,41 @@
psData.pbuf_head = buffer - PSBUFF_DL_HEADER_OFFSET;
#endif
psData.datalen = length;
+
+ unsigned char header[40] = {0};
+ if(unlikely(g_xlat_dev) && g_xlat_dev == dev->net && ((*(uint8_t *)psData.pbuf_data)&0xf0) == 0x60 && (g_xlat_dev->flags & IFF_UP)){
+ struct iphdr *ip_h = header;
+ struct ipv6hdr *ip6_h = (struct ipv6hdr *)psData.pbuf_data;
+ memcpy(header + sizeof(struct iphdr), psData.pbuf_data + sizeof(struct ipv6hdr), 4);
+ if(fill_ip_header(ip_h, ip6_h) && fast_nat_check(ip_h)){//
+ uint32_t old_sum, new_sum;
+ uint16_t checksum, len_left;
+ uint8_t protocol = ip6_h->nexthdr;
+
+ len_left = ntohs(ip6_h->payload_len);
+ old_sum = ipv6_pseudo_header_checksum(psData.pbuf_data, len_left, protocol);
+ new_sum = ipv4_pseudo_header_checksum(ip_h, len_left);
+ ip_h->check = ip_checksum(ip_h, sizeof(struct iphdr));
+ if (protocol == IPPROTO_TCP) {
+ struct tcphdr *tcp_targ = (struct tcphdr *)(psData.pbuf_data + sizeof(struct ipv6hdr));
+ checksum = ip_checksum_adjust(tcp_targ->check, old_sum, new_sum);
+ tcp_targ->check = checksum;
+ psData.pbuf_data = psData.pbuf_data + sizeof(struct ipv6hdr) - sizeof(struct iphdr);
+ memcpy(psData.pbuf_data, ip_h, sizeof(struct iphdr));
+ psData.datalen = psData.datalen - sizeof(struct ipv6hdr) + sizeof(struct iphdr);
+ }else if (protocol == IPPROTO_UDP) {
+ struct udphdr *udp_targ = (struct udphdr *)(psData.pbuf_data + sizeof(struct ipv6hdr));
+ if(udp_targ->check){
+ checksum = ip_checksum_adjust(udp_targ->check, old_sum, new_sum);
+ udp_targ->check = checksum;
+ }
+ psData.pbuf_data = psData.pbuf_data + sizeof(struct ipv6hdr) - sizeof(struct iphdr);
+ memcpy(psData.pbuf_data, ip_h, sizeof(struct iphdr));
+ psData.datalen = psData.datalen - sizeof(struct ipv6hdr) + sizeof(struct iphdr);
+ }
+ }
+ }
+
skb = skb_build_psbuf(&psData);
if (!skb)
@@ -369,7 +455,7 @@
int err;
struct psnet *dev;
struct net_device *net;
-
+ g_set_xlat_cb = psnet_set_xlat;
dbg("ddr_ap_net_lan_init.\n");
err = -ENOMEM;
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/tun.c b/ap/os/linux/linux-3.4.x/drivers/net/tun.c
old mode 100644
new mode 100755
index 8e8b74e..3309fc9
--- a/ap/os/linux/linux-3.4.x/drivers/net/tun.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/tun.c
@@ -603,7 +603,7 @@
return skb;
}
-
+extern int (*fast_from_softirq) (struct sk_buff *skb);
/* Get packet from user space buffer */
static ssize_t tun_get_user(struct tun_struct *tun,
const struct iovec *iv, size_t count,
@@ -733,7 +733,12 @@
skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
skb_shinfo(skb)->gso_segs = 0;
}
-
+ if (fast_from_softirq && fast_from_softirq(skb))
+ {
+ tun->dev->stats.rx_packets++;
+ tun->dev->stats.rx_bytes += len;
+ return count;
+ }
netif_rx_ni(skb);
tun->dev->stats.rx_packets++;
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 4b5bcbd..fa499d5 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
@@ -9,6 +9,10 @@
#include <linux/icmp.h>
#include <net/ip.h>
#include <linux/if_arp.h>
+#include <linux/if_addr.h>
+#include <linux/ipv6.h>
+#include <net/ipv6.h>
+#include <net/protocol.h>
#include <linux/inetdevice.h>
#include <linux/netfilter.h>
@@ -350,6 +354,14 @@
void fast_tcpdump(struct sk_buff *skb);
struct sk_buff *fast_expand_headroom(struct sk_buff *skb, struct net_device *dev);
struct sk_buff *fast_expand_headroom_v6(struct sk_buff *skb, struct net_device *dev);
+uint32_t ip_checksum_add(uint32_t current_value, const void *data, int len);
+uint16_t ip_checksum_finish(uint32_t temp_sum);
+uint16_t ip_checksum(const void *data, int len);
+
+uint32_t ipv6_pseudo_header_checksum(const struct ipv6hdr *ip6, uint16_t len, uint8_t protocol);
+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);
#endif //_FAST_COMMON_H
diff --git a/ap/os/linux/linux-3.4.x/net/core/SI/net_cache.c b/ap/os/linux/linux-3.4.x/net/core/SI/net_cache.c
index 4d20226..ae038f9 100755
--- a/ap/os/linux/linux-3.4.x/net/core/SI/net_cache.c
+++ b/ap/os/linux/linux-3.4.x/net/core/SI/net_cache.c
@@ -33,7 +33,7 @@
//#include "../kmap_skb.h"
#include <linux/wakelock.h>
-
+#include <linux/if_arp.h>
#include <linux/hash.h>
/***************************************************************************************************************/
/***************************************************************************************************************/
@@ -148,6 +148,10 @@
skb_invalid_cache(skb,skb->len + PSBUF_HEAD_SPACE + PDCP_INCREMENT_SPACE);
//invalid_cache(skb->data - NET_SKB_PAD , NET_SKB_PAD );
}
+ else if(unlikely(skb->indev != NULL && skb->indev->type == ARPHRD_NONE))
+ {
+ clean_cache(skb->data, skb->len);
+ }
else
{
//fast_nat_recvÖУ¬ÔÚfast_nat_find³É¹¦Ö®ºó£¬Ö´ÐÐskb_reset_network_header£¬½øÐÐIP°üµÄ¸³Öµ
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 ad5210e..239a88f 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
@@ -2495,6 +2495,121 @@
fast_release_all(RELEASE_ALL_SK);
}
}
+/* function: ip_checksum_add
+ * adds data to a checksum
+ * current_value - the current checksum (or 0 to start a new checksum)
+ * data - the data to add to the checksum
+ * len - length of data
+ */
+uint32_t ip_checksum_add(uint32_t current_value, const void *data, int len) {
+ uint32_t checksum = current_value;
+ int left = len;
+ const uint16_t *data_16 = data;
+
+ while(left > 1) {
+ checksum += *data_16;
+ data_16++;
+ left -= 2;
+ }
+ if(left) {
+ checksum += *(uint8_t *)data_16;
+ }
+
+ return checksum;
+}
+
+/* function: ip_checksum_fold
+ * folds a 32-bit partial checksum into 16 bits
+ * temp_sum - sum from ip_checksum_add
+ * returns: the folded checksum in network byte order
+ */
+uint16_t ip_checksum_fold(uint32_t temp_sum) {
+ while(temp_sum > 0xffff)
+ temp_sum = (temp_sum >> 16) + (temp_sum & 0xFFFF);
+
+ return temp_sum;
+}
+
+/* function: ip_checksum_finish
+ * folds and closes the checksum
+ * temp_sum - sum from ip_checksum_add
+ * returns: a header checksum value in network byte order
+ */
+uint16_t ip_checksum_finish(uint32_t temp_sum) {
+ return ~ip_checksum_fold(temp_sum);
+}
+
+/* function: ip_checksum
+ * combined ip_checksum_add and ip_checksum_finish
+ * data - data to checksum
+ * len - length of data
+ */
+uint16_t ip_checksum(const void *data, int len) {
+ uint32_t temp_sum;
+
+ temp_sum = ip_checksum_add(0,data,len);
+ return ip_checksum_finish(temp_sum);
+}
+
+/* function: ipv6_pseudo_header_checksum
+ * calculate the pseudo header checksum for use in tcp/udp/icmp headers
+ * ip6 - the ipv6 header
+ * len - the transport length (transport header + payload)
+ * protocol - the transport layer protocol, can be different from ip6->ip6_nxt for fragments
+ */
+uint32_t ipv6_pseudo_header_checksum(const struct ipv6hdr *ip6, uint16_t len, uint8_t protocol) {
+ uint32_t checksum_len, checksum_next;
+ checksum_len = htonl((uint32_t) len);
+ checksum_next = htonl(protocol);
+
+ uint32_t current_value = 0;
+ current_value = ip_checksum_add(current_value, &(ip6->saddr), sizeof(struct in6_addr));
+ current_value = ip_checksum_add(current_value, &(ip6->daddr), sizeof(struct in6_addr));
+ current_value = ip_checksum_add(current_value, &checksum_len, sizeof(checksum_len));
+ current_value = ip_checksum_add(current_value, &checksum_next, sizeof(checksum_next));
+
+ return current_value;
+}
+
+/* function: ipv4_pseudo_header_checksum
+ * calculate the pseudo header checksum for use in tcp/udp headers
+ * ip - the ipv4 header
+ * len - the transport length (transport header + payload)
+ */
+uint32_t ipv4_pseudo_header_checksum(const struct iphdr *ip, uint16_t len) {
+ uint16_t temp_protocol, temp_length;
+
+ temp_protocol = htons(ip->protocol);
+ temp_length = htons(len);
+
+ uint32_t current_value = 0;
+ current_value = ip_checksum_add(current_value, &(ip->saddr), sizeof(uint32_t));
+ current_value = ip_checksum_add(current_value, &(ip->daddr), sizeof(uint32_t));
+ current_value = ip_checksum_add(current_value, &temp_protocol, sizeof(uint16_t));
+ current_value = ip_checksum_add(current_value, &temp_length, sizeof(uint16_t));
+
+ return current_value;
+}
+
+/* function: ip_checksum_adjust
+ * calculates a new checksum given a previous checksum and the old and new pseudo-header checksums
+ * checksum - the header checksum in the original packet in network byte order
+ * old_hdr_sum - the pseudo-header checksum of the original packet
+ * new_hdr_sum - the pseudo-header checksum of the translated packet
+ * returns: the new header checksum in network byte order
+ */
+uint16_t ip_checksum_adjust(uint16_t checksum, uint32_t old_hdr_sum, uint32_t new_hdr_sum) {
+ // Algorithm suggested in RFC 1624.
+ // http://tools.ietf.org/html/rfc1624#section-3
+ checksum = ~checksum;
+ uint16_t folded_sum = ip_checksum_fold(checksum + new_hdr_sum);
+ uint16_t folded_old = ip_checksum_fold(old_hdr_sum);
+ if (folded_sum > folded_old) {
+ return ~(folded_sum - folded_old);
+ } else {
+ return ~(folded_sum - folded_old - 1); // end-around borrow
+ }
+}
//¼Ç¼ÓÐDST_NOCACHE±êÖ¾µÄdst³öÏֵĴÎÊý
int no_cache = 0;
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 fd96151..837c4c7 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
@@ -44,6 +44,44 @@
/* **************************** º¯ÊýʵÏÖ ************************ */
+
+int fast_nat_check(unsigned char *data)
+{
+ struct iphdr *iph = NULL;
+ struct udphdr *udph = NULL;
+ struct tcphdr *tcph = NULL;
+ struct nf_conntrack_tuple tuple = {0};
+ fast_entry_data_t *nat_entry_data = NULL;
+
+ if (!data)
+ return 0;
+ iph = (struct iphdr *)data;
+
+ /* only tcp/udp */
+ if (IPPROTO_UDP == iph->protocol){
+ udph = (struct udphdr *)(data + iph->ihl * 4);
+ tuple.src.u.udp.port = udph->source;
+ tuple.dst.u.udp.port = udph->dest;
+ }else if (IPPROTO_TCP == iph->protocol){
+ tcph = (struct tcphdr *)(data + iph->ihl * 4);
+ tuple.src.u.tcp.port = tcph->source;
+ tuple.dst.u.tcp.port = tcph->dest;
+ }else{
+ return 0;
+ }
+
+ tuple.src.l3num = AF_INET;
+ tuple.src.u3.ip = iph->saddr;
+ tuple.dst.u3.ip = iph->daddr;
+ tuple.dst.protonum = iph->protocol;
+ tuple.dst.dir = IP_CT_DIR_ORIGINAL;
+
+ rcu_read_lock();
+ nat_entry_data = fast_find_entry_data(working_hash, &tuple);
+ rcu_read_unlock();
+ return (nat_entry_data != NULL);
+}
+
/*»ñÈ¡±¨ÎÄÎåÔª×éÐÅÏ¢*/
int fast_nat_get_tuple(struct sk_buff *skb, struct nf_conntrack_tuple *tuple)
{
@@ -125,6 +163,10 @@
#ifndef CONFIG_PREEMPT_RT_FULL
extern int *vir_addr_ddrnet;
#endif
+struct in6_addr g_plat_subnet;
+struct in6_addr g_ipv6_local_subnet;
+struct in_addr g_ipv4_local_subnet;
+struct net_device *g_xlat_dev;
//ipv4Êý¾Ý°üµÄ¿ìËÙ´¦Àí£¬hashÓÃRCU»úÖÆ½øÐб£»¤£¬×ܵÄÁ¬½ÓÁ´±íÓÃspin½øÐб£»¤
int fast_nat_recv(struct sk_buff *skb)
{
@@ -401,12 +443,37 @@
if (skb->dev->flags & IFF_UP)
{
//pppÖ»ÐèÒª´«ÊäIP°ü
- if (skb->dev->type == ARPHRD_PPP)//(strncmp(skb->dev->name, ppp_name, strlen(ppp_name)) == 0)
+ if (skb->dev->type == ARPHRD_PPP || skb->dev->type == ARPHRD_NONE)//(strncmp(skb->dev->name, ppp_name, strlen(ppp_name)) == 0)
{
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)
{
//print_sun(SUN_DBG, "fastnat-2 dev_queue_xmit, send to:%s !!!!!!!! \n", skb->dev->name);
@@ -524,7 +591,7 @@
if (memcmp(dst->_neighbour->ha, zeromac, ETH_ALEN) == 0)
{
- if (strncmp(out->name, ppp_name, strlen(ppp_name)) != 0)
+ if (strncmp(out->name, ppp_name, strlen(ppp_name)) != 0 && strncmp(out->name, "v4-", 3) != 0)
{
return NF_ACCEPT;
}