diff --git a/[refs] b/[refs] index 956a50b6468d..cf1e9ba257ff 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e7de369050534025b33aab1033358bf47a577e4d +refs/heads/master: 7ae69d2aa4ed3ee8cef18a072346366f019d6a4a diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 71693c5c3137..0db72a36e245 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -2519,19 +2519,6 @@ P: Romain Lievin M: roms@lpg.ticalc.org S: Maintained -TIPC NETWORK LAYER -P: Per Liden -M: per.liden@nospam.ericsson.com -P: Jon Maloy -M: jon.maloy@nospam.ericsson.com -P: Allan Stephens -M: allan.stephens@nospam.windriver.com -L: tipc-discussion@lists.sourceforge.net -W: http://tipc.sourceforge.net/ -W: http://tipc.cslab.ericsson.net/ -T: git tipc.cslab.ericsson.net:/pub/git/tipc.git -S: Maintained - TLAN NETWORK DRIVER P: Samuel Chessman M: chessman@tux.org diff --git a/trunk/arch/ia64/kernel/fsys.S b/trunk/arch/ia64/kernel/fsys.S index 2ddbac6f4999..ce423910ca97 100644 --- a/trunk/arch/ia64/kernel/fsys.S +++ b/trunk/arch/ia64/kernel/fsys.S @@ -903,5 +903,6 @@ fsyscall_table: data8 0 data8 0 data8 0 + data8 0 // 1280 .org fsyscall_table + 8*NR_syscalls // guard against failures to increase NR_syscalls diff --git a/trunk/arch/powerpc/Makefile b/trunk/arch/powerpc/Makefile index 44dd82b791d1..d3654a264ef7 100644 --- a/trunk/arch/powerpc/Makefile +++ b/trunk/arch/powerpc/Makefile @@ -139,14 +139,17 @@ drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ -# Default to zImage, override when needed -defaultimage-y := zImage +defaultimage-$(CONFIG_PPC32) := zImage defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux +defaultimage-$(CONFIG_PPC_PSERIES) := zImage KBUILD_IMAGE := $(defaultimage-y) all: $(KBUILD_IMAGE) CPPFLAGS_vmlinux.lds := -Upowerpc +# All the instructions talk about "make bzImage". +bzImage: zImage + BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage .PHONY: $(BOOT_TARGETS) diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 788dec4c7ef3..b53d677f6742 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -25,8 +25,8 @@ HOSTCC := gcc BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \ $(shell $(CROSS32CC) -print-file-name=include) -fPIC BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc +BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds OBJCOPYFLAGS := contents,alloc,load,readonly,data -OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000 zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h @@ -35,7 +35,7 @@ zliblinuxheader := zlib.h zconf.h zutil.h $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) #$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h) -src-boot := crt0.S string.S prom.c stdio.c main.c div64.S +src-boot := string.S prom.c main.c div64.S crt0.S src-boot += $(zlib) src-boot := $(addprefix $(obj)/, $(src-boot)) obj-boot := $(addsuffix .o, $(basename $(src-boot))) @@ -70,7 +70,7 @@ quiet_cmd_bootas = BOOTAS $@ cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $< quiet_cmd_bootld = BOOTLD $@ - cmd_bootld = $(CROSS32LD) -T $(srctree)/$(src)/$(3) -o $@ $(2) + cmd_bootld = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(2) $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c $(call if_changed_dep,bootcc) @@ -87,14 +87,12 @@ obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) -hostprogs-y := addnote addRamDisk hack-coff - -targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \ - zImage.coff zImage.initrd.coff \ - $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ - $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ - $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ - vmlinux.initrd +hostprogs-y := addnote addRamDisk +targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \ + $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ + $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ + $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \ + vmlinux.initrd extra-y := initrd.o quiet_cmd_ramdisk = RAMDISK $@ @@ -116,10 +114,6 @@ quiet_cmd_addsection = ADDSEC $@ quiet_cmd_addnote = ADDNOTE $@ cmd_addnote = $(obj)/addnote $@ -quiet_cmd_gencoff = COFF $@ - cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $@ && \ - $(obj)/hack-coff $@ - $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % $(call if_changed,gzip) @@ -133,35 +127,22 @@ $(call obj-sec, $(required) $(initrd)): $(obj)/kernel-%.o: $(obj)/kernel-%.c $(call if_changed_dep,bootcc) $(call cmd,addsection) -$(obj)/zImage.vmode $(obj)/zImage.coff: obj-boot += $(call obj-sec, $(required)) +$(obj)/zImage.vmode: obj-boot += $(call obj-sec, $(required)) $(obj)/zImage.vmode: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.lds - $(call cmd,bootld,$(obj-boot),zImage.lds) + $(call cmd,bootld,$(obj-boot)) -$(obj)/zImage.initrd.vmode $(obj)/zImage.initrd.coff: obj-boot += $(call obj-sec, $(required) $(initrd)) +$(obj)/zImage.initrd.vmode: obj-boot += $(call obj-sec, $(required) $(initrd)) $(obj)/zImage.initrd.vmode: $(call obj-sec, $(required) $(initrd)) $(obj-boot) $(srctree)/$(src)/zImage.lds - $(call cmd,bootld,$(obj-boot),zImage.lds) - -# For 32-bit powermacs, build the COFF images as well as the ELF images. -coffimage-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.coff -coffrdimg-$(CONFIG_PPC_PMAC)-$(CONFIG_PPC32) := $(obj)/zImage.initrd.coff + $(call cmd,bootld,$(obj-boot)) -$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote $(coffimage-y-y) +$(obj)/zImage: $(obj)/zImage.vmode $(obj)/addnote @cp -f $< $@ $(call if_changed,addnote) -$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote $(coffrdimg-y-y) +$(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote @cp -f $< $@ $(call if_changed,addnote) -$(obj)/zImage.coff: $(call obj-sec, $(required)) $(obj-boot) $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff - $(call cmd,bootld,$(obj-boot),zImage.coff.lds) - $(call cmd,gencoff) - -$(obj)/zImage.initrd.coff: $(call obj-sec, $(required) $(initrd)) $(obj-boot) \ - $(srctree)/$(src)/zImage.coff.lds $(obj)/hack-coff - $(call cmd,bootld,$(obj-boot),zImage.coff.lds) - $(call cmd,gencoff) - #----------------------------------------------------------- # build u-boot images #----------------------------------------------------------- diff --git a/trunk/arch/powerpc/boot/crt0.S b/trunk/arch/powerpc/boot/crt0.S index e0192c26037b..d2f2ace56cd3 100644 --- a/trunk/arch/powerpc/boot/crt0.S +++ b/trunk/arch/powerpc/boot/crt0.S @@ -12,23 +12,17 @@ #include "ppc_asm.h" .text - /* a procedure descriptor used when booting this as a COFF file */ -_zimage_start_opd: - .long _zimage_start, 0, 0, 0 - .globl _zimage_start _zimage_start: - /* Work out the offset between the address we were linked at - and the address where we're running. */ bl 1f -1: mflr r0 + +1: + mflr r0 lis r9,1b@ha addi r9,r9,1b@l subf. r0,r9,r0 - beq 3f /* if running at same address as linked */ + beq 3f - /* The .got2 section contains a list of addresses, so add - the address offset onto each entry. */ lis r9,__got2_start@ha addi r9,r9,__got2_start@l lis r8,__got2_end@ha @@ -38,14 +32,15 @@ _zimage_start: srwi. r8,r8,2 mtctr r8 add r9,r0,r9 -2: lwz r8,0(r9) +2: + lwz r8,0(r9) add r8,r8,r0 stw r8,0(r9) addi r9,r9,4 bdnz 2b - /* Do a cache flush for our text, in case OF didn't */ -3: lis r9,_start@h +3: + lis r9,_start@h add r9,r0,r9 lis r8,_etext@ha addi r8,r8,_etext@l diff --git a/trunk/arch/powerpc/boot/hack-coff.c b/trunk/arch/powerpc/boot/hack-coff.c deleted file mode 100644 index 5e5a6573a1ef..000000000000 --- a/trunk/arch/powerpc/boot/hack-coff.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * hack-coff.c - hack the header of an xcoff file to fill in - * a few fields needed by the Open Firmware xcoff loader on - * Power Macs but not initialized by objcopy. - * - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include -#include -#include -#include "rs6000.h" - -#define AOUT_MAGIC 0x010b - -#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \ - + ((unsigned char *)(x))[1]) -#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \ - ((unsigned char *)(x))[1] = (v) & 0xff) -#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \ - + (((unsigned char *)(x))[1] << 16) \ - + (((unsigned char *)(x))[2] << 8) \ - + ((unsigned char *)(x))[3]) - -int -main(int ac, char **av) -{ - int fd; - int i, nsect; - int aoutsz; - struct external_filehdr fhdr; - AOUTHDR aout; - struct external_scnhdr shdr; - - if (ac != 2) { - fprintf(stderr, "Usage: hack-coff coff-file\n"); - exit(1); - } - if ((fd = open(av[1], 2)) == -1) { - perror(av[2]); - exit(1); - } - if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr)) - goto readerr; - i = get_16be(fhdr.f_magic); - if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) { - fprintf(stderr, "%s: not an xcoff file\n", av[1]); - exit(1); - } - aoutsz = get_16be(fhdr.f_opthdr); - if (read(fd, &aout, aoutsz) != aoutsz) - goto readerr; - nsect = get_16be(fhdr.f_nscns); - for (i = 0; i < nsect; ++i) { - if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) - goto readerr; - if (strcmp(shdr.s_name, ".text") == 0) { - put_16be(aout.o_snentry, i+1); - put_16be(aout.o_sntext, i+1); - } else if (strcmp(shdr.s_name, ".data") == 0) { - put_16be(aout.o_sndata, i+1); - } else if (strcmp(shdr.s_name, ".bss") == 0) { - put_16be(aout.o_snbss, i+1); - } - } - put_16be(aout.magic, AOUT_MAGIC); - if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1 - || write(fd, &aout, aoutsz) != aoutsz) { - fprintf(stderr, "%s: write error\n", av[1]); - exit(1); - } - close(fd); - exit(0); - -readerr: - fprintf(stderr, "%s: read error or file too short\n", av[1]); - exit(1); -} diff --git a/trunk/arch/powerpc/boot/main.c b/trunk/arch/powerpc/boot/main.c index 55ec59867250..64ec93116fa6 100644 --- a/trunk/arch/powerpc/boot/main.c +++ b/trunk/arch/powerpc/boot/main.c @@ -21,8 +21,8 @@ extern void flush_cache(void *, unsigned long); /* Value picked to match that used by yaboot */ -#define PROG_START 0x01400000 /* only used on 64-bit systems */ -#define RAM_END (512<<20) /* Fixme: use OF */ +#define PROG_START 0x01400000 +#define RAM_END (512<<20) // Fixme: use OF */ #define ONE_MB 0x100000 extern char _start[]; @@ -160,17 +160,6 @@ static int is_elf64(void *hdr) elfoffset = (unsigned long)elf64ph->p_offset; vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset; vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset; - -#if defined(PROG_START) - /* - * Maintain a "magic" minimum address. This keeps some older - * firmware platforms running. - */ - - if (claim_base < PROG_START) - claim_base = PROG_START; -#endif - return 1; } @@ -217,18 +206,12 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) exit(); if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) exit(); + stderr = stdout; + if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) + exit(); printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp); - /* - * The first available claim_base must be above the end of the - * the loaded kernel wrapper file (_start to _end includes the - * initrd image if it is present) and rounded up to a nice - * 1 MB boundary for good measure. - */ - - claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); - vmlinuz.addr = (unsigned long)_vmlinux_start; vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); @@ -245,6 +228,25 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) exit(); } + /* + * The first available claim_base must be above the end of the + * the loaded kernel wrapper file (_start to _end includes the + * initrd image if it is present) and rounded up to a nice + * 1 MB boundary for good measure. + */ + + claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB); + +#if defined(PROG_START) + /* + * Maintain a "magic" minimum address. This keeps some older + * firmware platforms running. + */ + + if (claim_base < PROG_START) + claim_base = PROG_START; +#endif + /* We need to claim the memsize plus the file offset since gzip * will expand the header (file offset), then the kernel, then * possible rubbish we don't care about. But the kernel bss must diff --git a/trunk/arch/powerpc/boot/prom.c b/trunk/arch/powerpc/boot/prom.c index fa0057736f6b..4bea2f4dcb06 100644 --- a/trunk/arch/powerpc/boot/prom.c +++ b/trunk/arch/powerpc/boot/prom.c @@ -13,153 +13,487 @@ #include "prom.h" int (*prom)(void *); -phandle chosen_handle; -ihandle stdout; -int call_prom(const char *service, int nargs, int nret, ...) +void *chosen_handle; + +void *stdin; +void *stdout; +void *stderr; + + +int +write(void *handle, void *ptr, int nb) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *ihandle; + void *addr; + int len; + int actual; + } args; + + args.service = "write"; + args.nargs = 3; + args.nret = 1; + args.ihandle = handle; + args.addr = ptr; + args.len = nb; + args.actual = -1; + (*prom)(&args); + return args.actual; +} + +int +read(void *handle, void *ptr, int nb) { - int i; struct prom_args { - const char *service; + char *service; int nargs; int nret; - unsigned int args[12]; + void *ihandle; + void *addr; + int len; + int actual; } args; - va_list list; - args.service = service; - args.nargs = nargs; - args.nret = nret; + args.service = "read"; + args.nargs = 3; + args.nret = 1; + args.ihandle = handle; + args.addr = ptr; + args.len = nb; + args.actual = -1; + (*prom)(&args); + return args.actual; +} - va_start(list, nret); - for (i = 0; i < nargs; i++) - args.args[i] = va_arg(list, unsigned int); - va_end(list); +void +exit() +{ + struct prom_args { + char *service; + } args; - for (i = 0; i < nret; i++) - args.args[nargs+i] = 0; + for (;;) { + args.service = "exit"; + (*prom)(&args); + } +} - if (prom(&args) < 0) - return -1; +void +pause(void) +{ + struct prom_args { + char *service; + } args; - return (nret > 0)? args.args[nargs]: 0; + args.service = "enter"; + (*prom)(&args); } -int call_prom_ret(const char *service, int nargs, int nret, - unsigned int *rets, ...) +void * +finddevice(const char *name) { - int i; struct prom_args { - const char *service; + char *service; int nargs; int nret; - unsigned int args[12]; + const char *devspec; + void *phandle; } args; - va_list list; - args.service = service; - args.nargs = nargs; - args.nret = nret; + args.service = "finddevice"; + args.nargs = 1; + args.nret = 1; + args.devspec = name; + args.phandle = (void *) -1; + (*prom)(&args); + return args.phandle; +} - va_start(list, rets); - for (i = 0; i < nargs; i++) - args.args[i] = va_arg(list, unsigned int); - va_end(list); +void * +claim(unsigned long virt, unsigned long size, unsigned long align) +{ + struct prom_args { + char *service; + int nargs; + int nret; + unsigned int virt; + unsigned int size; + unsigned int align; + void *ret; + } args; + + args.service = "claim"; + args.nargs = 3; + args.nret = 1; + args.virt = virt; + args.size = size; + args.align = align; + (*prom)(&args); + return args.ret; +} + +int +getprop(void *phandle, const char *name, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *phandle; + const char *name; + void *buf; + int buflen; + int size; + } args; - for (i = 0; i < nret; i++) - args.args[nargs+i] = 0; + args.service = "getprop"; + args.nargs = 4; + args.nret = 1; + args.phandle = phandle; + args.name = name; + args.buf = buf; + args.buflen = buflen; + args.size = -1; + (*prom)(&args); + return args.size; +} - if (prom(&args) < 0) - return -1; +int +putc(int c, void *f) +{ + char ch = c; - if (rets != (void *) 0) - for (i = 1; i < nret; ++i) - rets[i-1] = args.args[nargs+i]; + if (c == '\n') + putc('\r', f); + return write(f, &ch, 1) == 1? c: -1; +} - return (nret > 0)? args.args[nargs]: 0; +int +putchar(int c) +{ + return putc(c, stdout); } -int write(void *handle, void *ptr, int nb) +int +fputs(char *str, void *f) { - return call_prom("write", 3, 1, handle, ptr, nb); + int n = strlen(str); + + return write(f, str, n) == n? 0: -1; } -/* - * Older OF's require that when claiming a specific range of addresses, - * we claim the physical space in the /memory node and the virtual - * space in the chosen mmu node, and then do a map operation to - * map virtual to physical. +size_t strnlen(const char * s, size_t count) +{ + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} + +extern unsigned int __div64_32(unsigned long long *dividend, + unsigned int divisor); + +/* The unnecessary pointer compare is there + * to check for type safety (n must be 64bit) */ -static int need_map = -1; -static ihandle chosen_mmu; -static phandle memory; +# define do_div(n,base) ({ \ + unsigned int __base = (base); \ + unsigned int __rem; \ + (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ + if (((n) >> 32) == 0) { \ + __rem = (unsigned int)(n) % __base; \ + (n) = (unsigned int)(n) / __base; \ + } else \ + __rem = __div64_32(&(n), __base); \ + __rem; \ + }) -/* returns true if s2 is a prefix of s1 */ -static int string_match(const char *s1, const char *s2) +static int skip_atoi(const char **s) { - for (; *s2; ++s2) - if (*s1++ != *s2) - return 0; - return 1; + int i, c; + + for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s) + i = i*10 + c - '0'; + return i; } -static int check_of_version(void) +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ + +static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) { - phandle oprom, chosen; - char version[64]; + char c,sign,tmp[66]; + const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; + int i; - oprom = finddevice("/openprom"); - if (oprom == (phandle) -1) + if (type & LARGE) + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) return 0; - if (getprop(oprom, "model", version, sizeof(version)) <= 0) - return 0; - version[sizeof(version)-1] = 0; - printf("OF version = '%s'\r\n", version); - if (!string_match(version, "Open Firmware, 1.") - && !string_match(version, "FirmWorks,3.")) - return 0; - chosen = finddevice("/chosen"); - if (chosen == (phandle) -1) { - chosen = finddevice("/chosen@0"); - if (chosen == (phandle) -1) { - printf("no chosen\n"); - return 0; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if ((signed long long)num < 0) { + sign = '-'; + num = - (signed long long)num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; } } - if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) { - printf("no mmu\n"); - return 0; + if (type & SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; } - memory = (ihandle) call_prom("open", 1, 1, "/memory"); - if (memory == (ihandle) -1) { - memory = (ihandle) call_prom("open", 1, 1, "/memory@0"); - if (memory == (ihandle) -1) { - printf("no memory node\n"); - return 0; + i = 0; + if (num == 0) + tmp[i++]='0'; + else while (num != 0) { + tmp[i++] = digits[do_div(num, base)]; + } + if (i > precision) + precision = i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base==8) + *str++ = '0'; + else if (base==16) { + *str++ = '0'; + *str++ = digits[33]; } } - printf("old OF detected\r\n"); - return 1; + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + return str; } -void *claim(unsigned long virt, unsigned long size, unsigned long align) +int vsprintf(char *buf, const char *fmt, va_list args) { - int ret; - unsigned int result; + int len; + unsigned long long num; + int i, base; + char * str; + const char *s; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier; /* 'h', 'l', or 'L' for integer fields */ + /* 'z' support added 23/7/1999 S.H. */ + /* 'z' changed to 'Z' --davidm 1/25/99 */ - if (need_map < 0) - need_map = check_of_version(); - if (align || !need_map) - return (void *) call_prom("claim", 3, 1, virt, size, align); - ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory, - align, size, virt); - if (ret != 0 || result == -1) - return (void *) -1; - ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu, - align, size, virt); - /* 0x12 == coherent + read/write */ - ret = call_prom("call-method", 6, 1, "map", chosen_mmu, - 0x12, size, virt, virt); - return (void *) virt; + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if ('0' <= *fmt && *fmt <= '9') + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if ('0' <= *fmt && *fmt <= '9') + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { + qualifier = *fmt; + ++fmt; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, char *); + if (!s) + s = ""; + + len = strnlen(s, precision); + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + continue; + + + case 'n': + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = (str - buf); + } else if (qualifier == 'Z') { + size_t * ip = va_arg(args, size_t *); + *ip = (str - buf); + } else { + int * ip = va_arg(args, int *); + *ip = (str - buf); + } + continue; + + case '%': + *str++ = '%'; + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + if (qualifier == 'l') { + num = va_arg(args, unsigned long); + if (flags & SIGN) + num = (signed long) num; + } else if (qualifier == 'Z') { + num = va_arg(args, size_t); + } else if (qualifier == 'h') { + num = (unsigned short) va_arg(args, int); + if (flags & SIGN) + num = (signed short) num; + } else { + num = va_arg(args, unsigned int); + if (flags & SIGN) + num = (signed int) num; + } + str = number(str, num, base, field_width, precision, flags); + } + *str = '\0'; + return str-buf; +} + +int sprintf(char * buf, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i=vsprintf(buf,fmt,args); + va_end(args); + return i; +} + +static char sprint_buf[1024]; + +int +printf(const char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + write(stdout, sprint_buf, n); + return n; } diff --git a/trunk/arch/powerpc/boot/prom.h b/trunk/arch/powerpc/boot/prom.h index 3e2ddd4a5a81..96ab5aec740c 100644 --- a/trunk/arch/powerpc/boot/prom.h +++ b/trunk/arch/powerpc/boot/prom.h @@ -1,34 +1,18 @@ #ifndef _PPC_BOOT_PROM_H_ #define _PPC_BOOT_PROM_H_ -typedef void *phandle; -typedef void *ihandle; - extern int (*prom) (void *); -extern phandle chosen_handle; -extern ihandle stdout; +extern void *chosen_handle; -int call_prom(const char *service, int nargs, int nret, ...); -int call_prom_ret(const char *service, int nargs, int nret, - unsigned int *rets, ...); +extern void *stdin; +extern void *stdout; +extern void *stderr; extern int write(void *handle, void *ptr, int nb); -extern void *claim(unsigned long virt, unsigned long size, unsigned long aln); - -static inline void exit(void) -{ - call_prom("exit", 0, 0); -} - -static inline phandle finddevice(const char *name) -{ - return (phandle) call_prom("finddevice", 1, 1, name); -} - -static inline int getprop(void *phandle, const char *name, - void *buf, int buflen) -{ - return call_prom("getprop", 4, 1, phandle, name, buf, buflen); -} - +extern int read(void *handle, void *ptr, int nb); +extern void exit(void); +extern void pause(void); +extern void *finddevice(const char *); +extern void *claim(unsigned long virt, unsigned long size, unsigned long align); +extern int getprop(void *phandle, const char *name, void *buf, int buflen); #endif /* _PPC_BOOT_PROM_H_ */ diff --git a/trunk/arch/powerpc/boot/rs6000.h b/trunk/arch/powerpc/boot/rs6000.h deleted file mode 100644 index 433f45084e41..000000000000 --- a/trunk/arch/powerpc/boot/rs6000.h +++ /dev/null @@ -1,243 +0,0 @@ -/* IBM RS/6000 "XCOFF" file definitions for BFD. - Copyright (C) 1990, 1991 Free Software Foundation, Inc. - FIXME: Can someone provide a transliteration of this name into ASCII? - Using the following chars caused a compiler warning on HIUX (so I replaced - them with octal escapes), and isn't useful without an understanding of what - character set it is. - Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM - and John Gilmore of Cygnus Support. */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - /* IBM RS/6000 */ -#define U802WRMAGIC 0730 /* writeable text segments **chh** */ -#define U802ROMAGIC 0735 /* readonly sharable text segments */ -#define U802TOCMAGIC 0737 /* readonly text segments and TOC */ - -#define BADMAG(x) \ - ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \ - (x).f_magic != U802TOCMAGIC) - -#define FILHDR struct external_filehdr -#define FILHSZ 20 - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - unsigned char magic[2]; /* type of file */ - unsigned char vstamp[2]; /* version stamp */ - unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */ - unsigned char dsize[4]; /* initialized data " " */ - unsigned char bsize[4]; /* uninitialized data " " */ - unsigned char entry[4]; /* entry pt. */ - unsigned char text_start[4]; /* base of text used for this file */ - unsigned char data_start[4]; /* base of data used for this file */ - unsigned char o_toc[4]; /* address of TOC */ - unsigned char o_snentry[2]; /* section number of entry point */ - unsigned char o_sntext[2]; /* section number of .text section */ - unsigned char o_sndata[2]; /* section number of .data section */ - unsigned char o_sntoc[2]; /* section number of TOC */ - unsigned char o_snloader[2]; /* section number of .loader section */ - unsigned char o_snbss[2]; /* section number of .bss section */ - unsigned char o_algntext[2]; /* .text alignment */ - unsigned char o_algndata[2]; /* .data alignment */ - unsigned char o_modtype[2]; /* module type (??) */ - unsigned char o_cputype[2]; /* cpu type */ - unsigned char o_maxstack[4]; /* max stack size (??) */ - unsigned char o_maxdata[4]; /* max data size (??) */ - unsigned char o_resv2[12]; /* reserved */ -} -AOUTHDR; - -#define AOUTSZ 72 -#define SMALL_AOUTSZ (28) -#define AOUTHDRSZ 72 - -#define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */ -#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */ -#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */ - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _PAD ".pad" -#define _LOADER ".loader" - -#define SCNHDR struct external_scnhdr -#define SCNHSZ 40 - -/* XCOFF uses a special .loader section with type STYP_LOADER. */ -#define STYP_LOADER 0x1000 - -/* XCOFF uses a special .debug section with type STYP_DEBUG. */ -#define STYP_DEBUG 0x2000 - -/* XCOFF handles line number or relocation overflow by creating - another section header with STYP_OVRFLO set. */ -#define STYP_OVRFLO 0x8000 - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - - -#define LINENO struct external_lineno -#define LINESZ 6 - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - struct { - unsigned char x_scnlen[4]; - unsigned char x_parmhash[4]; - unsigned char x_snhash[2]; - unsigned char x_smtyp[1]; - unsigned char x_smclas[1]; - unsigned char x_stab[4]; - unsigned char x_snstab[2]; - } x_csect; - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 -#define DBXMASK 0x80 /* for dbx storage mask */ -#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK) - - - -/********************** RELOCATION DIRECTIVES **********************/ - - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_size[1]; - char r_type[1]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 10 - -#define DEFAULT_DATA_SECTION_ALIGNMENT 4 -#define DEFAULT_BSS_SECTION_ALIGNMENT 4 -#define DEFAULT_TEXT_SECTION_ALIGNMENT 4 -/* For new sections we havn't heard of before */ -#define DEFAULT_SECTION_ALIGNMENT 4 diff --git a/trunk/arch/powerpc/boot/stdio.c b/trunk/arch/powerpc/boot/stdio.c deleted file mode 100644 index b5aa522f8b77..000000000000 --- a/trunk/arch/powerpc/boot/stdio.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include "string.h" -#include "stdio.h" -#include "prom.h" - -size_t strnlen(const char * s, size_t count) -{ - const char *sc; - - for (sc = s; count-- && *sc != '\0'; ++sc) - /* nothing */; - return sc - s; -} - -extern unsigned int __div64_32(unsigned long long *dividend, - unsigned int divisor); - -/* The unnecessary pointer compare is there - * to check for type safety (n must be 64bit) - */ -# define do_div(n,base) ({ \ - unsigned int __base = (base); \ - unsigned int __rem; \ - (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ - if (((n) >> 32) == 0) { \ - __rem = (unsigned int)(n) % __base; \ - (n) = (unsigned int)(n) / __base; \ - } else \ - __rem = __div64_32(&(n), __base); \ - __rem; \ - }) - -static int skip_atoi(const char **s) -{ - int i, c; - - for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s) - i = i*10 + c - '0'; - return i; -} - -#define ZEROPAD 1 /* pad with zero */ -#define SIGN 2 /* unsigned/signed long */ -#define PLUS 4 /* show plus */ -#define SPACE 8 /* space if plus */ -#define LEFT 16 /* left justified */ -#define SPECIAL 32 /* 0x */ -#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ - -static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) -{ - char c,sign,tmp[66]; - const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; - int i; - - if (type & LARGE) - digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - if (type & LEFT) - type &= ~ZEROPAD; - if (base < 2 || base > 36) - return 0; - c = (type & ZEROPAD) ? '0' : ' '; - sign = 0; - if (type & SIGN) { - if ((signed long long)num < 0) { - sign = '-'; - num = - (signed long long)num; - size--; - } else if (type & PLUS) { - sign = '+'; - size--; - } else if (type & SPACE) { - sign = ' '; - size--; - } - } - if (type & SPECIAL) { - if (base == 16) - size -= 2; - else if (base == 8) - size--; - } - i = 0; - if (num == 0) - tmp[i++]='0'; - else while (num != 0) { - tmp[i++] = digits[do_div(num, base)]; - } - if (i > precision) - precision = i; - size -= precision; - if (!(type&(ZEROPAD+LEFT))) - while(size-->0) - *str++ = ' '; - if (sign) - *str++ = sign; - if (type & SPECIAL) { - if (base==8) - *str++ = '0'; - else if (base==16) { - *str++ = '0'; - *str++ = digits[33]; - } - } - if (!(type & LEFT)) - while (size-- > 0) - *str++ = c; - while (i < precision--) - *str++ = '0'; - while (i-- > 0) - *str++ = tmp[i]; - while (size-- > 0) - *str++ = ' '; - return str; -} - -int vsprintf(char *buf, const char *fmt, va_list args) -{ - int len; - unsigned long long num; - int i, base; - char * str; - const char *s; - - int flags; /* flags to number() */ - - int field_width; /* width of output field */ - int precision; /* min. # of digits for integers; max - number of chars for from string */ - int qualifier; /* 'h', 'l', or 'L' for integer fields */ - /* 'z' support added 23/7/1999 S.H. */ - /* 'z' changed to 'Z' --davidm 1/25/99 */ - - - for (str=buf ; *fmt ; ++fmt) { - if (*fmt != '%') { - *str++ = *fmt; - continue; - } - - /* process flags */ - flags = 0; - repeat: - ++fmt; /* this also skips first '%' */ - switch (*fmt) { - case '-': flags |= LEFT; goto repeat; - case '+': flags |= PLUS; goto repeat; - case ' ': flags |= SPACE; goto repeat; - case '#': flags |= SPECIAL; goto repeat; - case '0': flags |= ZEROPAD; goto repeat; - } - - /* get field width */ - field_width = -1; - if ('0' <= *fmt && *fmt <= '9') - field_width = skip_atoi(&fmt); - else if (*fmt == '*') { - ++fmt; - /* it's the next argument */ - field_width = va_arg(args, int); - if (field_width < 0) { - field_width = -field_width; - flags |= LEFT; - } - } - - /* get the precision */ - precision = -1; - if (*fmt == '.') { - ++fmt; - if ('0' <= *fmt && *fmt <= '9') - precision = skip_atoi(&fmt); - else if (*fmt == '*') { - ++fmt; - /* it's the next argument */ - precision = va_arg(args, int); - } - if (precision < 0) - precision = 0; - } - - /* get the conversion qualifier */ - qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { - qualifier = *fmt; - ++fmt; - } - - /* default base */ - base = 10; - - switch (*fmt) { - case 'c': - if (!(flags & LEFT)) - while (--field_width > 0) - *str++ = ' '; - *str++ = (unsigned char) va_arg(args, int); - while (--field_width > 0) - *str++ = ' '; - continue; - - case 's': - s = va_arg(args, char *); - if (!s) - s = ""; - - len = strnlen(s, precision); - - if (!(flags & LEFT)) - while (len < field_width--) - *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = *s++; - while (len < field_width--) - *str++ = ' '; - continue; - - case 'p': - if (field_width == -1) { - field_width = 2*sizeof(void *); - flags |= ZEROPAD; - } - str = number(str, - (unsigned long) va_arg(args, void *), 16, - field_width, precision, flags); - continue; - - - case 'n': - if (qualifier == 'l') { - long * ip = va_arg(args, long *); - *ip = (str - buf); - } else if (qualifier == 'Z') { - size_t * ip = va_arg(args, size_t *); - *ip = (str - buf); - } else { - int * ip = va_arg(args, int *); - *ip = (str - buf); - } - continue; - - case '%': - *str++ = '%'; - continue; - - /* integer number formats - set up the flags and "break" */ - case 'o': - base = 8; - break; - - case 'X': - flags |= LARGE; - case 'x': - base = 16; - break; - - case 'd': - case 'i': - flags |= SIGN; - case 'u': - break; - - default: - *str++ = '%'; - if (*fmt) - *str++ = *fmt; - else - --fmt; - continue; - } - if (qualifier == 'l') { - num = va_arg(args, unsigned long); - if (flags & SIGN) - num = (signed long) num; - } else if (qualifier == 'Z') { - num = va_arg(args, size_t); - } else if (qualifier == 'h') { - num = (unsigned short) va_arg(args, int); - if (flags & SIGN) - num = (signed short) num; - } else { - num = va_arg(args, unsigned int); - if (flags & SIGN) - num = (signed int) num; - } - str = number(str, num, base, field_width, precision, flags); - } - *str = '\0'; - return str-buf; -} - -int sprintf(char * buf, const char *fmt, ...) -{ - va_list args; - int i; - - va_start(args, fmt); - i=vsprintf(buf,fmt,args); - va_end(args); - return i; -} - -static char sprint_buf[1024]; - -int -printf(const char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - write(stdout, sprint_buf, n); - return n; -} diff --git a/trunk/arch/powerpc/boot/stdio.h b/trunk/arch/powerpc/boot/stdio.h index eb9e16c87aef..24bd3a8dee94 100644 --- a/trunk/arch/powerpc/boot/stdio.h +++ b/trunk/arch/powerpc/boot/stdio.h @@ -7,4 +7,10 @@ extern int sprintf(char *buf, const char *fmt, ...); extern int vsprintf(char *buf, const char *fmt, va_list args); +extern int putc(int c, void *f); +extern int putchar(int c); +extern int getchar(void); + +extern int fputs(char *str, void *f); + #endif /* _PPC_BOOT_STDIO_H_ */ diff --git a/trunk/arch/powerpc/boot/string.S b/trunk/arch/powerpc/boot/string.S index ac3d43b6a324..b1eeaed7db17 100644 --- a/trunk/arch/powerpc/boot/string.S +++ b/trunk/arch/powerpc/boot/string.S @@ -107,12 +107,10 @@ memcpy: rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ addi r6,r3,-4 addi r4,r4,-4 - beq 3f /* if less than 8 bytes to do */ + beq 2f /* if less than 8 bytes to do */ andi. r0,r6,3 /* get dest word aligned */ mtctr r7 bne 5f - andi. r0,r4,3 /* check src word aligned too */ - bne 3f 1: lwz r7,4(r4) lwzu r8,8(r4) stw r7,4(r6) @@ -134,11 +132,6 @@ memcpy: bdnz 4b blr 5: subfic r0,r0,4 - cmpw cr1,r0,r5 - add r7,r0,r4 - andi. r7,r7,3 /* will source be word-aligned too? */ - ble cr1,3b - bne 3b /* do byte-by-byte if not */ mtctr r0 6: lbz r7,4(r4) addi r4,r4,1 @@ -156,12 +149,10 @@ backwards_memcpy: rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ add r6,r3,r5 add r4,r4,r5 - beq 3f + beq 2f andi. r0,r6,3 mtctr r7 bne 5f - andi. r0,r4,3 - bne 3f 1: lwz r7,-4(r4) lwzu r8,-8(r4) stw r7,-4(r6) @@ -180,12 +171,7 @@ backwards_memcpy: stbu r0,-1(r6) bdnz 4b blr -5: cmpw cr1,r0,r5 - subf r7,r0,r4 - andi. r7,r7,3 - ble cr1,3b - bne 3b - mtctr r0 +5: mtctr r0 6: lbzu r7,-1(r4) stbu r7,-1(r6) bdnz 6b diff --git a/trunk/arch/powerpc/boot/zImage.coff.lds b/trunk/arch/powerpc/boot/zImage.coff.lds deleted file mode 100644 index 6016251a1a2c..000000000000 --- a/trunk/arch/powerpc/boot/zImage.coff.lds +++ /dev/null @@ -1,46 +0,0 @@ -OUTPUT_ARCH(powerpc:common) -ENTRY(_start) -SECTIONS -{ - . = (5*1024*1024); - _start = .; - .text : - { - *(.text) - *(.fixup) - } - _etext = .; - . = ALIGN(4096); - .data : - { - *(.rodata*) - *(.data*) - *(.sdata*) - __got2_start = .; - *(.got2) - __got2_end = .; - - _vmlinux_start = .; - *(.kernel:vmlinux.strip) - _vmlinux_end = .; - - _initrd_start = .; - *(.kernel:initrd) - _initrd_end = .; - } - - . = ALIGN(4096); - _edata = .; - __bss_start = .; - .bss : - { - *(.sbss) - *(.bss) - } - _end = . ; - - /DISCARD/ : - { - *(.comment) - } -} diff --git a/trunk/arch/powerpc/configs/mpc834x_sys_defconfig b/trunk/arch/powerpc/configs/mpc834x_sys_defconfig deleted file mode 100644 index 3bff761965c2..000000000000 --- a/trunk/arch/powerpc/configs/mpc834x_sys_defconfig +++ /dev/null @@ -1,911 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.15-g461d4edf-dirty -# Fri Jan 13 11:01:47 2006 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_PPC_UDBG_16550=y -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_DEFAULT_UIMAGE=y - -# -# Processor support -# -# CONFIG_CLASSIC32 is not set -# CONFIG_PPC_52xx is not set -# CONFIG_PPC_82xx is not set -CONFIG_PPC_83xx=y -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -# CONFIG_E500 is not set -CONFIG_6xx=y -CONFIG_83xx=y -CONFIG_PPC_FPU=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_SMP is not set - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_EMBEDDED=y -# CONFIG_KALLSYMS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -CONFIG_SLAB=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set - -# -# Block layer -# -# CONFIG_LBD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_PPC_GEN550=y -# CONFIG_WANT_EARLY_SERIAL is not set - -# -# Platform support -# -CONFIG_MPC834x_SYS=y -CONFIG_MPC834x=y - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_GENERIC_ISA_DMA=y -# CONFIG_PPC_I8259 is not set -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_FSL_SOC=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_LEGACY_PROC is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=y -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -CONFIG_E100=y -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -# CONFIG_GFAR_NAPI is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_83xx_WDT=y - -# -# PCI-based Watchdog Cards -# -# CONFIG_PCIPCWATCHDOG is not set -# CONFIG_WDTPCI is not set -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_SENSORS_M41T00 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# SN Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set - -# -# Instrumentation Support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_BOOTX_TEXT is not set -# CONFIG_SERIAL_TEXT_DEBUG is not set -# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -# CONFIG_PPC_EARLY_DEBUG_G5 is not set -# CONFIG_PPC_EARLY_DEBUG_RTAS is not set -# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# SEC2.x Options -# -CONFIG_MPC8349E_SEC2x=y - -# -# SEC2.x Test Options -# -CONFIG_MPC8349E_SEC2xTEST=y diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index 840aad43a98b..56399c5c931a 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -135,7 +135,7 @@ int main(void) DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); - DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr)); + DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca)); DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); diff --git a/trunk/arch/powerpc/kernel/cpu_setup_power4.S b/trunk/arch/powerpc/kernel/cpu_setup_power4.S index b61d86e7ceb6..cca942fe6115 100644 --- a/trunk/arch/powerpc/kernel/cpu_setup_power4.S +++ b/trunk/arch/powerpc/kernel/cpu_setup_power4.S @@ -130,7 +130,7 @@ _GLOBAL(__save_cpu_setup) mfcr r7 /* Get storage ptr */ - LOAD_REG_IMMEDIATE(r5,cpu_state_storage) + LOADADDR(r5,cpu_state_storage) /* We only deal with 970 for now */ mfspr r0,SPRN_PVR @@ -164,7 +164,7 @@ _GLOBAL(__restore_cpu_setup) /* Get storage ptr (FIXME when using anton reloc as we * are running with translation disabled here */ - LOAD_REG_IMMEDIATE(r5,cpu_state_storage) + LOADADDR(r5,cpu_state_storage) /* We only deal with 970 for now */ mfspr r0,SPRN_PVR diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index 10696456a4c6..43c74a6b07b1 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -55,8 +55,7 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); #define COMMON_USER_POWER4 (COMMON_USER_PPC64 | PPC_FEATURE_POWER4) #define COMMON_USER_POWER5 (COMMON_USER_PPC64 | PPC_FEATURE_POWER5) #define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS) -#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ - PPC_FEATURE_BOOKE) + /* We only set the spe features if the kernel was compiled with * spe support @@ -80,8 +79,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/power3", - .oprofile_type = PPC_OPROFILE_RS64, - .platform = "power3", + .oprofile_type = RS64, }, { /* Power3+ */ .pvr_mask = 0xffff0000, @@ -94,8 +92,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/power3", - .oprofile_type = PPC_OPROFILE_RS64, - .platform = "power3", + .oprofile_type = RS64, }, { /* Northstar */ .pvr_mask = 0xffff0000, @@ -108,8 +105,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = PPC_OPROFILE_RS64, - .platform = "rs64", + .oprofile_type = RS64, }, { /* Pulsar */ .pvr_mask = 0xffff0000, @@ -122,8 +118,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = PPC_OPROFILE_RS64, - .platform = "rs64", + .oprofile_type = RS64, }, { /* I-star */ .pvr_mask = 0xffff0000, @@ -136,8 +131,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = PPC_OPROFILE_RS64, - .platform = "rs64", + .oprofile_type = RS64, }, { /* S-star */ .pvr_mask = 0xffff0000, @@ -150,8 +144,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = PPC_OPROFILE_RS64, - .platform = "rs64", + .oprofile_type = RS64, }, { /* Power4 */ .pvr_mask = 0xffff0000, @@ -164,8 +157,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_power4, .oprofile_cpu_type = "ppc64/power4", - .oprofile_type = PPC_OPROFILE_POWER4, - .platform = "power4", + .oprofile_type = POWER4, }, { /* Power4+ */ .pvr_mask = 0xffff0000, @@ -178,8 +170,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_power4, .oprofile_cpu_type = "ppc64/power4", - .oprofile_type = PPC_OPROFILE_POWER4, - .platform = "power4", + .oprofile_type = POWER4, }, { /* PPC970 */ .pvr_mask = 0xffff0000, @@ -193,8 +184,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", - .oprofile_type = PPC_OPROFILE_POWER4, - .platform = "ppc970", + .oprofile_type = POWER4, }, #endif /* CONFIG_PPC64 */ #if defined(CONFIG_PPC64) || defined(CONFIG_POWER4) @@ -214,8 +204,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", - .oprofile_type = PPC_OPROFILE_POWER4, - .platform = "ppc970", + .oprofile_type = POWER4, }, #endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */ #ifdef CONFIG_PPC64 @@ -230,8 +219,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .cpu_setup = __setup_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", - .oprofile_type = PPC_OPROFILE_POWER4, - .platform = "ppc970", + .oprofile_type = POWER4, }, { /* Power5 GR */ .pvr_mask = 0xffff0000, @@ -244,8 +232,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_power4, .oprofile_cpu_type = "ppc64/power5", - .oprofile_type = PPC_OPROFILE_POWER4, - .platform = "power5", + .oprofile_type = POWER4, }, { /* Power5 GS */ .pvr_mask = 0xffff0000, @@ -258,8 +245,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_power4, .oprofile_cpu_type = "ppc64/power5+", - .oprofile_type = PPC_OPROFILE_POWER4, - .platform = "power5+", + .oprofile_type = POWER4, }, { /* Cell Broadband Engine */ .pvr_mask = 0xffff0000, @@ -271,7 +257,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_be, - .platform = "ppc-cell-be", }, { /* default match */ .pvr_mask = 0x00000000, @@ -283,7 +268,6 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 6, .cpu_setup = __setup_cpu_power4, - .platform = "power4", } #endif /* CONFIG_PPC64 */ #ifdef CONFIG_PPC32 @@ -297,7 +281,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc601", }, { /* 603 */ .pvr_mask = 0xffff0000, @@ -307,8 +290,7 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, - .platform = "ppc603", + .cpu_setup = __setup_cpu_603 }, { /* 603e */ .pvr_mask = 0xffff0000, @@ -318,8 +300,7 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, - .platform = "ppc603", + .cpu_setup = __setup_cpu_603 }, { /* 603ev */ .pvr_mask = 0xffff0000, @@ -329,8 +310,7 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, - .platform = "ppc603", + .cpu_setup = __setup_cpu_603 }, { /* 604 */ .pvr_mask = 0xffff0000, @@ -341,8 +321,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 2, - .cpu_setup = __setup_cpu_604, - .platform = "ppc604", + .cpu_setup = __setup_cpu_604 }, { /* 604e */ .pvr_mask = 0xfffff000, @@ -353,8 +332,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_604, - .platform = "ppc604", + .cpu_setup = __setup_cpu_604 }, { /* 604r */ .pvr_mask = 0xffff0000, @@ -365,8 +343,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_604, - .platform = "ppc604", + .cpu_setup = __setup_cpu_604 }, { /* 604ev */ .pvr_mask = 0xffff0000, @@ -377,8 +354,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_604, - .platform = "ppc604", + .cpu_setup = __setup_cpu_604 }, { /* 740/750 (0x4202, don't support TAU ?) */ .pvr_mask = 0xffffffff, @@ -389,8 +365,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750 }, { /* 750CX (80100 and 8010x?) */ .pvr_mask = 0xfffffff0, @@ -401,8 +376,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750cx, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750cx }, { /* 750CX (82201 and 82202) */ .pvr_mask = 0xfffffff0, @@ -413,8 +387,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750cx, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750cx }, { /* 750CXe (82214) */ .pvr_mask = 0xfffffff0, @@ -425,8 +398,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750cx, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750cx }, { /* 750CXe "Gekko" (83214) */ .pvr_mask = 0xffffffff, @@ -437,8 +409,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750cx, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750cx }, { /* 745/755 */ .pvr_mask = 0xfffff000, @@ -449,8 +420,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750 }, { /* 750FX rev 1.x */ .pvr_mask = 0xffffff00, @@ -461,8 +431,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750 }, { /* 750FX rev 2.0 must disable HID0[DPM] */ .pvr_mask = 0xffffffff, @@ -473,8 +442,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750 }, { /* 750FX (All revs except 2.0) */ .pvr_mask = 0xffff0000, @@ -485,8 +453,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750fx, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750fx }, { /* 750GX */ .pvr_mask = 0xffff0000, @@ -497,8 +464,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750fx, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750fx }, { /* 740/750 (L2CR bit need fixup for 740) */ .pvr_mask = 0xffff0000, @@ -509,8 +475,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, - .platform = "ppc750", + .cpu_setup = __setup_cpu_750 }, { /* 7400 rev 1.1 ? (no TAU) */ .pvr_mask = 0xffffffff, @@ -521,8 +486,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_7400, - .platform = "ppc7400", + .cpu_setup = __setup_cpu_7400 }, { /* 7400 */ .pvr_mask = 0xffff0000, @@ -533,8 +497,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_7400, - .platform = "ppc7400", + .cpu_setup = __setup_cpu_7400 }, { /* 7410 */ .pvr_mask = 0xffff0000, @@ -545,8 +508,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .cpu_setup = __setup_cpu_7410, - .platform = "ppc7400", + .cpu_setup = __setup_cpu_7410 }, { /* 7450 2.0 - no doze/nap */ .pvr_mask = 0xffffffff, @@ -559,8 +521,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7450 2.1 */ .pvr_mask = 0xffffffff, @@ -573,8 +534,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7450 2.3 and newer */ .pvr_mask = 0xffff0000, @@ -587,8 +547,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7455 rev 1.x */ .pvr_mask = 0xffffff00, @@ -601,8 +560,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7455 rev 2.0 */ .pvr_mask = 0xffffffff, @@ -615,8 +573,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7455 others */ .pvr_mask = 0xffff0000, @@ -629,8 +586,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7447/7457 Rev 1.0 */ .pvr_mask = 0xffffffff, @@ -643,8 +599,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7447/7457 Rev 1.1 */ .pvr_mask = 0xffffffff, @@ -657,8 +612,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7447/7457 Rev 1.2 and later */ .pvr_mask = 0xffff0000, @@ -671,8 +625,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7447A */ .pvr_mask = 0xffff0000, @@ -685,8 +638,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 7448 */ .pvr_mask = 0xffff0000, @@ -699,8 +651,7 @@ struct cpu_spec cpu_specs[] = { .num_pmcs = 6, .cpu_setup = __setup_cpu_745x, .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, - .platform = "ppc7450", + .oprofile_type = G4, }, { /* 82xx (8240, 8245, 8260 are all 603e cores) */ .pvr_mask = 0x7fff0000, @@ -710,8 +661,7 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, - .platform = "ppc603", + .cpu_setup = __setup_cpu_603 }, { /* All G2_LE (603e core, plus some) have the same pvr */ .pvr_mask = 0x7fff0000, @@ -721,8 +671,7 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, - .platform = "ppc603", + .cpu_setup = __setup_cpu_603 }, { /* e300 (a 603e core, plus some) on 83xx */ .pvr_mask = 0x7fff0000, @@ -732,8 +681,7 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, - .platform = "ppc603", + .cpu_setup = __setup_cpu_603 }, { /* default match, we assume split I/D cache & TB (non-601)... */ .pvr_mask = 0x00000000, @@ -743,7 +691,6 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc603", }, #endif /* CLASSIC_PPC */ #ifdef CONFIG_8xx @@ -757,7 +704,6 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 16, .dcache_bsize = 16, - .platform = "ppc823", }, #endif /* CONFIG_8xx */ #ifdef CONFIG_40x @@ -769,7 +715,6 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 16, .dcache_bsize = 16, - .platform = "ppc403", }, { /* 403GCX */ .pvr_mask = 0xffffff00, @@ -780,7 +725,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB, .icache_bsize = 16, .dcache_bsize = 16, - .platform = "ppc403", }, { /* 403G ?? */ .pvr_mask = 0xffff0000, @@ -790,7 +734,6 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 16, .dcache_bsize = 16, - .platform = "ppc403", }, { /* 405GP */ .pvr_mask = 0xffff0000, @@ -801,7 +744,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* STB 03xxx */ .pvr_mask = 0xffff0000, @@ -812,7 +754,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* STB 04xxx */ .pvr_mask = 0xffff0000, @@ -823,7 +764,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* NP405L */ .pvr_mask = 0xffff0000, @@ -834,7 +774,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* NP4GS3 */ .pvr_mask = 0xffff0000, @@ -845,7 +784,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* NP405H */ .pvr_mask = 0xffff0000, @@ -856,7 +794,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* 405GPr */ .pvr_mask = 0xffff0000, @@ -867,7 +804,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* STBx25xx */ .pvr_mask = 0xffff0000, @@ -878,7 +814,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* 405LP */ .pvr_mask = 0xffff0000, @@ -888,7 +823,6 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* Xilinx Virtex-II Pro */ .pvr_mask = 0xffff0000, @@ -899,7 +833,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, { /* 405EP */ .pvr_mask = 0xffff0000, @@ -910,7 +843,6 @@ struct cpu_spec cpu_specs[] = { PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc405", }, #endif /* CONFIG_40x */ @@ -920,90 +852,81 @@ struct cpu_spec cpu_specs[] = { .pvr_value = 0x40000850, .cpu_name = "440EP Rev. A", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, + .cpu_user_features = COMMON_USER, /* 440EP has an FPU */ .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440", }, { .pvr_mask = 0xf0000fff, .pvr_value = 0x400008d3, .cpu_name = "440EP Rev. B", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, + .cpu_user_features = COMMON_USER, /* 440EP has an FPU */ .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440", }, { /* 440GP Rev. B */ .pvr_mask = 0xf0000fff, .pvr_value = 0x40000440, .cpu_name = "440GP Rev. B", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE, + .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440gp", }, { /* 440GP Rev. C */ .pvr_mask = 0xf0000fff, .pvr_value = 0x40000481, .cpu_name = "440GP Rev. C", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE, + .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440gp", }, { /* 440GX Rev. A */ .pvr_mask = 0xf0000fff, .pvr_value = 0x50000850, .cpu_name = "440GX Rev. A", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE, + .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440", }, { /* 440GX Rev. B */ .pvr_mask = 0xf0000fff, .pvr_value = 0x50000851, .cpu_name = "440GX Rev. B", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE, + .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440", }, { /* 440GX Rev. C */ .pvr_mask = 0xf0000fff, .pvr_value = 0x50000892, .cpu_name = "440GX Rev. C", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE, + .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440", }, { /* 440GX Rev. F */ .pvr_mask = 0xf0000fff, .pvr_value = 0x50000894, .cpu_name = "440GX Rev. F", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE, + .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440", }, { /* 440SP Rev. A */ .pvr_mask = 0xff000fff, .pvr_value = 0x53000891, .cpu_name = "440SP Rev. A", .cpu_features = CPU_FTRS_44X, - .cpu_user_features = COMMON_USER_BOOKE, + .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440", }, { /* 440SPe Rev. A */ .pvr_mask = 0xff000fff, @@ -1011,10 +934,9 @@ struct cpu_spec cpu_specs[] = { .cpu_name = "440SPe Rev. A", .cpu_features = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, - .cpu_user_features = COMMON_USER_BOOKE, + .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "ppc440", }, #endif /* CONFIG_44x */ #ifdef CONFIG_FSL_BOOKE @@ -1024,11 +946,10 @@ struct cpu_spec cpu_specs[] = { .cpu_name = "e200z5", /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ .cpu_features = CPU_FTRS_E200, - .cpu_user_features = COMMON_USER_BOOKE | - PPC_FEATURE_HAS_EFP_SINGLE | + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_UNIFIED_CACHE, .dcache_bsize = 32, - .platform = "ppc5554", }, { /* e200z6 */ .pvr_mask = 0xfff00000, @@ -1036,12 +957,11 @@ struct cpu_spec cpu_specs[] = { .cpu_name = "e200z6", /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ .cpu_features = CPU_FTRS_E200, - .cpu_user_features = COMMON_USER_BOOKE | - PPC_FEATURE_SPE_COMP | + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_UNIFIED_CACHE, .dcache_bsize = 32, - .platform = "ppc5554", }, { /* e500 */ .pvr_mask = 0xffff0000, @@ -1049,15 +969,14 @@ struct cpu_spec cpu_specs[] = { .cpu_name = "e500", /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ .cpu_features = CPU_FTRS_E500, - .cpu_user_features = COMMON_USER_BOOKE | - PPC_FEATURE_SPE_COMP | + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | PPC_FEATURE_HAS_EFP_SINGLE, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, .oprofile_cpu_type = "ppc/e500", - .oprofile_type = PPC_OPROFILE_BOOKE, - .platform = "ppc8540", + .oprofile_type = BOOKE, }, { /* e500v2 */ .pvr_mask = 0xffff0000, @@ -1065,16 +984,14 @@ struct cpu_spec cpu_specs[] = { .cpu_name = "e500v2", /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ .cpu_features = CPU_FTRS_E500_2, - .cpu_user_features = COMMON_USER_BOOKE | - PPC_FEATURE_SPE_COMP | - PPC_FEATURE_HAS_EFP_SINGLE | - PPC_FEATURE_HAS_EFP_DOUBLE, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP | + PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE, .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, .oprofile_cpu_type = "ppc/e500", - .oprofile_type = PPC_OPROFILE_BOOKE, - .platform = "ppc8548", + .oprofile_type = BOOKE, }, #endif #if !CLASSIC_PPC @@ -1086,7 +1003,6 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = PPC_FEATURE_32, .icache_bsize = 32, .dcache_bsize = 32, - .platform = "powerpc", } #endif /* !CLASSIC_PPC */ #endif /* CONFIG_PPC32 */ diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index d8da2a35c0a4..036b71d2adfc 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -988,7 +988,7 @@ _GLOBAL(enter_rtas) stwu r1,-INT_FRAME_SIZE(r1) mflr r0 stw r0,INT_FRAME_SIZE+4(r1) - LOAD_REG_ADDR(r4, rtas) + LOADADDR(r4, rtas) lis r6,1f@ha /* physical return address for rtas */ addi r6,r6,1f@l tophys(r6,r6) diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 542036318866..aacebb33e98a 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -511,8 +511,7 @@ restore: cmpdi 0,r5,0 beq 4f /* Check for pending interrupts (iSeries) */ - ld r3,PACALPPACAPTR(r13) - ld r3,LPPACAANYINT(r3) + ld r3,PACALPPACA+LPPACAANYINT(r13) cmpdi r3,0 beq+ 4f /* skip do_IRQ if no interrupts */ @@ -690,8 +689,9 @@ _GLOBAL(enter_rtas) std r6,PACASAVEDMSR(r13) /* Setup our real return addr */ - LOAD_REG_ADDR(r4,.rtas_return_loc) - clrldi r4,r4,2 /* convert to realmode address */ + SET_REG_TO_LABEL(r4,.rtas_return_loc) + SET_REG_TO_CONST(r9,PAGE_OFFSET) + sub r4,r4,r9 mtlr r4 li r0,0 @@ -706,7 +706,7 @@ _GLOBAL(enter_rtas) sync /* disable interrupts so SRR0/1 */ mtmsrd r0 /* don't get trashed */ - LOAD_REG_ADDR(r4, rtas) + SET_REG_TO_LABEL(r4,rtas) ld r5,RTASENTRY(r4) /* get the rtas->entry value */ ld r4,RTASBASE(r4) /* get the rtas->base value */ @@ -718,7 +718,8 @@ _GLOBAL(enter_rtas) _STATIC(rtas_return_loc) /* relocation is off at this point */ mfspr r4,SPRN_SPRG3 /* Get PACA */ - clrldi r4,r4,2 /* convert to realmode address */ + SET_REG_TO_CONST(r5, PAGE_OFFSET) + sub r4,r4,r5 /* RELOC the PACA base pointer */ mfmsr r6 li r0,MSR_RI @@ -727,7 +728,7 @@ _STATIC(rtas_return_loc) mtmsrd r6 ld r1,PACAR1(r4) /* Restore our SP */ - LOAD_REG_IMMEDIATE(r3,.rtas_restore_regs) + LOADADDR(r3,.rtas_restore_regs) ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ mtspr SPRN_SRR0,r3 diff --git a/trunk/arch/powerpc/kernel/fpu.S b/trunk/arch/powerpc/kernel/fpu.S index e4362dfa37fb..b780b42c95fc 100644 --- a/trunk/arch/powerpc/kernel/fpu.S +++ b/trunk/arch/powerpc/kernel/fpu.S @@ -39,9 +39,9 @@ _GLOBAL(load_up_fpu) * to another. Instead we call giveup_fpu in switch_to. */ #ifndef CONFIG_SMP - LOAD_REG_ADDRBASE(r3, last_task_used_math) + LOADBASE(r3, last_task_used_math) toreal(r3) - PPC_LL r4,ADDROFF(last_task_used_math)(r3) + PPC_LL r4,OFF(last_task_used_math)(r3) PPC_LCMPI 0,r4,0 beq 1f toreal(r4) @@ -77,7 +77,7 @@ _GLOBAL(load_up_fpu) #ifndef CONFIG_SMP subi r4,r5,THREAD fromreal(r4) - PPC_STL r4,ADDROFF(last_task_used_math)(r3) + PPC_STL r4,OFF(last_task_used_math)(r3) #endif /* CONFIG_SMP */ /* restore registers and return */ /* we haven't used ctr or xer or lr */ @@ -113,8 +113,8 @@ _GLOBAL(giveup_fpu) 1: #ifndef CONFIG_SMP li r5,0 - LOAD_REG_ADDRBASE(r4,last_task_used_math) - PPC_STL r5,ADDROFF(last_task_used_math)(r4) + LOADBASE(r4,last_task_used_math) + PPC_STL r5,OFF(last_task_used_math)(r4) #endif /* CONFIG_SMP */ blr diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index 308268466342..1c066d125375 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -154,12 +154,12 @@ _GLOBAL(__secondary_hold) bne 100b #ifdef CONFIG_HMT - SET_REG_IMMEDIATE(r4, .hmt_init) + LOADADDR(r4, .hmt_init) mtctr r4 bctr #else #ifdef CONFIG_SMP - LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init) + LOADADDR(r4, .pSeries_secondary_smp_init) mtctr r4 mr r3,r24 bctr @@ -205,10 +205,9 @@ exception_marker: #define EX_LR 72 /* - * We're short on space and time in the exception prolog, so we can't - * use the normal SET_REG_IMMEDIATE macro. Normally we just need the - * low halfword of the address, but for Kdump we need the whole low - * word. + * We're short on space and time in the exception prolog, so we can't use + * the normal LOADADDR macro. Normally we just need the low halfword of the + * address, but for Kdump we need the whole low word. */ #ifdef CONFIG_CRASH_DUMP #define LOAD_HANDLER(reg, label) \ @@ -255,9 +254,8 @@ exception_marker: #define EXCEPTION_PROLOG_ISERIES_2 \ mfmsr r10; \ - ld r12,PACALPPACAPTR(r13); \ - ld r11,LPPACASRR0(r12); \ - ld r12,LPPACASRR1(r12); \ + ld r11,PACALPPACA+LPPACASRR0(r13); \ + ld r12,PACALPPACA+LPPACASRR1(r13); \ ori r10,r10,MSR_RI; \ mtmsrd r10,1 @@ -636,8 +634,7 @@ data_access_slb_iSeries: std r12,PACA_EXSLB+EX_R12(r13) mfspr r10,SPRN_SPRG1 std r10,PACA_EXSLB+EX_R13(r13) - ld r12,PACALPPACAPTR(r13) - ld r12,LPPACASRR1(r12) + ld r12,PACALPPACA+LPPACASRR1(r13); b .slb_miss_realmode STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN) @@ -647,8 +644,7 @@ instruction_access_slb_iSeries: mtspr SPRN_SPRG1,r13 /* save r13 */ mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ std r3,PACA_EXSLB+EX_R3(r13) - ld r3,PACALPPACAPTR(r13) - ld r3,LPPACASRR0(r3) /* get SRR0 value */ + ld r3,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */ std r9,PACA_EXSLB+EX_R9(r13) mfcr r9 #ifdef __DISABLED__ @@ -660,8 +656,7 @@ instruction_access_slb_iSeries: std r12,PACA_EXSLB+EX_R12(r13) mfspr r10,SPRN_SPRG1 std r10,PACA_EXSLB+EX_R13(r13) - ld r12,PACALPPACAPTR(r13) - ld r12,LPPACASRR1(r12) + ld r12,PACALPPACA+LPPACASRR1(r13); b .slb_miss_realmode #ifdef __DISABLED__ @@ -718,7 +713,7 @@ system_reset_iSeries: lbz r23,PACAPROCSTART(r13) /* Test if this processor * should start */ sync - LOAD_REG_IMMEDIATE(r3,current_set) + LOADADDR(r3,current_set) sldi r28,r24,3 /* get current_set[cpu#] */ ldx r3,r3,r28 addi r1,r3,THREAD_SIZE @@ -750,19 +745,17 @@ iSeries_secondary_smp_loop: .globl decrementer_iSeries_masked decrementer_iSeries_masked: li r11,1 - ld r12,PACALPPACAPTR(r13) - stb r11,LPPACADECRINT(r12) - LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy) - lwz r12,ADDROFF(tb_ticks_per_jiffy)(r12) + stb r11,PACALPPACA+LPPACADECRINT(r13) + LOADBASE(r12,tb_ticks_per_jiffy) + lwz r12,OFF(tb_ticks_per_jiffy)(r12) mtspr SPRN_DEC,r12 /* fall through */ .globl hardware_interrupt_iSeries_masked hardware_interrupt_iSeries_masked: mtcrf 0x80,r9 /* Restore regs */ - ld r12,PACALPPACAPTR(r13) - ld r11,LPPACASRR0(r12) - ld r12,LPPACASRR1(r12) + ld r11,PACALPPACA+LPPACASRR0(r13) + ld r12,PACALPPACA+LPPACASRR1(r13) mtspr SPRN_SRR0,r11 mtspr SPRN_SRR1,r12 ld r9,PACA_EXGEN+EX_R9(r13) @@ -1001,8 +994,7 @@ _GLOBAL(slb_miss_realmode) ld r3,PACA_EXSLB+EX_R3(r13) lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ #ifdef CONFIG_PPC_ISERIES - ld r11,PACALPPACAPTR(r13) - ld r11,LPPACASRR0(r11) /* get SRR0 value */ + ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */ #endif /* CONFIG_PPC_ISERIES */ mtlr r10 @@ -1420,7 +1412,7 @@ _GLOBAL(pSeries_secondary_smp_init) * physical cpu id in r24, we need to search the pacas to find * which logical id maps to our physical one. */ - LOAD_REG_IMMEDIATE(r13, paca) /* Get base vaddr of paca array */ + LOADADDR(r13, paca) /* Get base vaddr of paca array */ li r5,0 /* logical cpu id */ 1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ cmpw r6,r24 /* Compare to our id */ @@ -1454,8 +1446,8 @@ _GLOBAL(pSeries_secondary_smp_init) #ifdef CONFIG_PPC_ISERIES _STATIC(__start_initialization_iSeries) /* Clear out the BSS */ - LOAD_REG_IMMEDIATE(r11,__bss_stop) - LOAD_REG_IMMEDIATE(r8,__bss_start) + LOADADDR(r11,__bss_stop) + LOADADDR(r8,__bss_start) sub r11,r11,r8 /* bss size */ addi r11,r11,7 /* round up to an even double word */ rldicl. r11,r11,61,3 /* shift right by 3 */ @@ -1466,17 +1458,17 @@ _STATIC(__start_initialization_iSeries) 3: stdu r0,8(r8) bdnz 3b 4: - LOAD_REG_IMMEDIATE(r1,init_thread_union) + LOADADDR(r1,init_thread_union) addi r1,r1,THREAD_SIZE li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) - LOAD_REG_IMMEDIATE(r3,cpu_specs) - LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) + LOADADDR(r3,cpu_specs) + LOADADDR(r4,cur_cpu_spec) li r5,0 bl .identify_cpu - LOAD_REG_IMMEDIATE(r2,__toc_start) + LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 @@ -1536,7 +1528,7 @@ _GLOBAL(__start_initialization_multiplatform) li r24,0 /* Switch off MMU if not already */ - LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) + LOADADDR(r4, .__after_prom_start - KERNELBASE) add r4,r4,r30 bl .__mmu_off b .__after_prom_start @@ -1556,7 +1548,7 @@ _STATIC(__boot_from_prom) /* put a relocation offset into r3 */ bl .reloc_offset - LOAD_REG_IMMEDIATE(r2,__toc_start) + LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 @@ -1596,9 +1588,9 @@ _STATIC(__after_prom_start) */ bl .reloc_offset mr r26,r3 - LOAD_REG_IMMEDIATE(r27, KERNELBASE) + SET_REG_TO_CONST(r27,KERNELBASE) - LOAD_REG_IMMEDIATE(r3, PHYSICAL_START) /* target addr */ + LOADADDR(r3, PHYSICAL_START) /* target addr */ // XXX FIXME: Use phys returned by OF (r30) add r4,r27,r26 /* source addr */ @@ -1606,7 +1598,7 @@ _STATIC(__after_prom_start) /* i.e. where we are running */ /* the source addr */ - LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ + LOADADDR(r5,copy_to_here) /* # bytes of memory to copy */ sub r5,r5,r27 li r6,0x100 /* Start offset, the first 0x100 */ @@ -1616,11 +1608,11 @@ _STATIC(__after_prom_start) /* this includes the code being */ /* executed here. */ - LOAD_REG_IMMEDIATE(r0, 4f) /* Jump to the copy of this code */ + LOADADDR(r0, 4f) /* Jump to the copy of this code */ mtctr r0 /* that we just made/relocated */ bctr -4: LOAD_REG_IMMEDIATE(r5,klimit) +4: LOADADDR(r5,klimit) add r5,r5,r26 ld r5,0(r5) /* get the value of klimit */ sub r5,r5,r27 @@ -1702,7 +1694,7 @@ _GLOBAL(pmac_secondary_start) mtmsrd r3 /* RI on */ /* Set up a paca value for this processor. */ - LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ + LOADADDR(r4, paca) /* Get base vaddr of paca array */ mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r4 /* for this processor. */ mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ @@ -1739,7 +1731,7 @@ _GLOBAL(__secondary_start) bl .early_setup_secondary /* Initialize the kernel stack. Just a repeat for iSeries. */ - LOAD_REG_ADDR(r3, current_set) + LOADADDR(r3,current_set) sldi r28,r24,3 /* get current_set[cpu#] */ ldx r1,r3,r28 addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD @@ -1750,8 +1742,8 @@ _GLOBAL(__secondary_start) mtlr r7 /* enable MMU and jump to start_secondary */ - LOAD_REG_ADDR(r3, .start_secondary_prolog) - LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) + LOADADDR(r3,.start_secondary_prolog) + SET_REG_TO_CONST(r4, MSR_KERNEL) #ifdef DO_SOFT_DISABLE ori r4,r4,MSR_EE #endif @@ -1800,8 +1792,8 @@ _STATIC(start_here_multiplatform) * be detached from the kernel completely. Besides, we need * to clear it now for kexec-style entry. */ - LOAD_REG_IMMEDIATE(r11,__bss_stop) - LOAD_REG_IMMEDIATE(r8,__bss_start) + LOADADDR(r11,__bss_stop) + LOADADDR(r8,__bss_start) sub r11,r11,r8 /* bss size */ addi r11,r11,7 /* round up to an even double word */ rldicl. r11,r11,61,3 /* shift right by 3 */ @@ -1839,7 +1831,7 @@ _STATIC(start_here_multiplatform) /* up the htab. This is done because we have relocated the */ /* kernel but are still running in real mode. */ - LOAD_REG_IMMEDIATE(r3,init_thread_union) + LOADADDR(r3,init_thread_union) add r3,r3,r26 /* set up a stack pointer (physical address) */ @@ -1848,14 +1840,14 @@ _STATIC(start_here_multiplatform) stdu r0,-STACK_FRAME_OVERHEAD(r1) /* set up the TOC (physical address) */ - LOAD_REG_IMMEDIATE(r2,__toc_start) + LOADADDR(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 add r2,r2,r26 - LOAD_REG_IMMEDIATE(r3, cpu_specs) + LOADADDR(r3,cpu_specs) add r3,r3,r26 - LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) + LOADADDR(r4,cur_cpu_spec) add r4,r4,r26 mr r5,r26 bl .identify_cpu @@ -1871,11 +1863,11 @@ _STATIC(start_here_multiplatform) * nowhere it can be initialized differently before we reach this * code */ - LOAD_REG_IMMEDIATE(r27, boot_cpuid) + LOADADDR(r27, boot_cpuid) add r27,r27,r26 lwz r27,0(r27) - LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ + LOADADDR(r24, paca) /* Get base vaddr of paca array */ mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ add r13,r13,r26 /* convert to physical addr */ @@ -1888,8 +1880,8 @@ _STATIC(start_here_multiplatform) mr r3,r31 bl .early_setup - LOAD_REG_IMMEDIATE(r3, .start_here_common) - LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) + LOADADDR(r3,.start_here_common) + SET_REG_TO_CONST(r4, MSR_KERNEL) mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 rfid @@ -1903,7 +1895,7 @@ _STATIC(start_here_common) /* The following code sets up the SP and TOC now that we are */ /* running with translation enabled. */ - LOAD_REG_IMMEDIATE(r3,init_thread_union) + LOADADDR(r3,init_thread_union) /* set up the stack */ addi r1,r3,THREAD_SIZE @@ -1916,16 +1908,16 @@ _STATIC(start_here_common) li r3,0 bl .do_cpu_ftr_fixups - LOAD_REG_IMMEDIATE(r26, boot_cpuid) + LOADADDR(r26, boot_cpuid) lwz r26,0(r26) - LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ + LOADADDR(r24, paca) /* Get base vaddr of paca array */ mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ mtspr SPRN_SPRG3,r13 /* ptr to current */ - LOAD_REG_IMMEDIATE(r4, init_task) + LOADADDR(r4,init_task) std r4,PACACURRENT(r13) /* Load the TOC */ @@ -1948,7 +1940,7 @@ _STATIC(start_here_common) _GLOBAL(hmt_init) #ifdef CONFIG_HMT - LOAD_REG_IMMEDIATE(r5, hmt_thread_data) + LOADADDR(r5, hmt_thread_data) mfspr r7,SPRN_PVR srwi r7,r7,16 cmpwi r7,0x34 /* Pulsar */ @@ -1969,7 +1961,7 @@ _GLOBAL(hmt_init) b 101f __hmt_secondary_hold: - LOAD_REG_IMMEDIATE(r5, hmt_thread_data) + LOADADDR(r5, hmt_thread_data) clrldi r5,r5,4 li r7,0 mfspr r6,SPRN_PIR @@ -1997,7 +1989,7 @@ __hmt_secondary_hold: #ifdef CONFIG_HMT _GLOBAL(hmt_start_secondary) - LOAD_REG_IMMEDIATE(r4,__hmt_secondary_hold) + LOADADDR(r4,__hmt_secondary_hold) clrldi r4,r4,4 mtspr SPRN_NIADORM, r4 mfspr r4, SPRN_MSRDORM diff --git a/trunk/arch/powerpc/kernel/idle_power4.S b/trunk/arch/powerpc/kernel/idle_power4.S index c16b4afab582..1494e2f177f7 100644 --- a/trunk/arch/powerpc/kernel/idle_power4.S +++ b/trunk/arch/powerpc/kernel/idle_power4.S @@ -38,14 +38,14 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) /* We must dynamically check for the NAP feature as it * can be cleared by CPU init after the fixups are done */ - LOAD_REG_ADDRBASE(r3,cur_cpu_spec) - ld r4,ADDROFF(cur_cpu_spec)(r3) + LOADBASE(r3,cur_cpu_spec) + ld r4,OFF(cur_cpu_spec)(r3) ld r4,CPU_SPEC_FEATURES(r4) andi. r0,r4,CPU_FTR_CAN_NAP beqlr /* Now check if user or arch enabled NAP mode */ - LOAD_REG_ADDRBASE(r3,powersave_nap) - lwz r4,ADDROFF(powersave_nap)(r3) + LOADBASE(r3,powersave_nap) + lwz r4,OFF(powersave_nap)(r3) cmpwi 0,r4,0 beqlr diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index d1fffce86df9..5651032d8706 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -238,10 +238,14 @@ void do_IRQ(struct pt_regs *regs) irq_exit(); #ifdef CONFIG_PPC_ISERIES - if (get_lppaca()->int_dword.fields.decr_int) { - get_lppaca()->int_dword.fields.decr_int = 0; - /* Signal a fake decrementer interrupt */ - timer_interrupt(regs); + { + struct paca_struct *lpaca = get_paca(); + + if (lpaca->lppaca.int_dword.fields.decr_int) { + lpaca->lppaca.int_dword.fields.decr_int = 0; + /* Signal a fake decrementer interrupt */ + timer_interrupt(regs); + } } #endif } diff --git a/trunk/arch/powerpc/kernel/lparcfg.c b/trunk/arch/powerpc/kernel/lparcfg.c index 1ae96a8ed7e2..9dda16ccde78 100644 --- a/trunk/arch/powerpc/kernel/lparcfg.c +++ b/trunk/arch/powerpc/kernel/lparcfg.c @@ -55,13 +55,15 @@ static unsigned long get_purr(void) { unsigned long sum_purr = 0; int cpu; + struct paca_struct *lpaca; for_each_cpu(cpu) { - sum_purr += lppaca[cpu].emulated_time_base; + lpaca = paca + cpu; + sum_purr += lpaca->lppaca.emulated_time_base; #ifdef PURR_DEBUG printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", - cpu, lppaca[cpu].emulated_time_base); + cpu, lpaca->lppaca.emulated_time_base); #endif } return sum_purr; @@ -77,11 +79,12 @@ static int lparcfg_data(struct seq_file *m, void *v) unsigned long pool_id, lp_index; int shared, entitled_capacity, max_entitled_capacity; int processors, max_processors; + struct paca_struct *lpaca = get_paca(); unsigned long purr = get_purr(); seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); - shared = (int)(get_lppaca()->shared_proc); + shared = (int)(lpaca->lppaca_ptr->shared_proc); seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", e2a(xItExtVpdPanel.mfgID[2]), e2a(xItExtVpdPanel.mfgID[3]), @@ -399,7 +402,7 @@ static int lparcfg_data(struct seq_file *m, void *v) (h_resource >> 0 * 8) & 0xffff); /* pool related entries are apropriate for shared configs */ - if (lppaca[0].shared_proc) { + if (paca[0].lppaca.shared_proc) { h_pic(&pool_idle_time, &pool_procs); @@ -448,7 +451,7 @@ static int lparcfg_data(struct seq_file *m, void *v) seq_printf(m, "partition_potential_processors=%d\n", partition_potential_processors); - seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc); + seq_printf(m, "shared_processor_mode=%d\n", paca[0].lppaca.shared_proc); return 0; } diff --git a/trunk/arch/powerpc/kernel/misc_32.S b/trunk/arch/powerpc/kernel/misc_32.S index be982023409e..01d0d97a16e1 100644 --- a/trunk/arch/powerpc/kernel/misc_32.S +++ b/trunk/arch/powerpc/kernel/misc_32.S @@ -68,7 +68,7 @@ _GLOBAL(reloc_offset) mflr r0 bl 1f 1: mflr r3 - LOAD_REG_IMMEDIATE(r4,1b) + LOADADDR(r4,1b) subf r3,r4,r3 mtlr r0 blr @@ -80,7 +80,7 @@ _GLOBAL(add_reloc_offset) mflr r0 bl 1f 1: mflr r5 - LOAD_REG_IMMEDIATE(r4,1b) + LOADADDR(r4,1b) subf r5,r4,r5 add r3,r3,r5 mtlr r0 diff --git a/trunk/arch/powerpc/kernel/misc_64.S b/trunk/arch/powerpc/kernel/misc_64.S index 2778cce058e2..ae48a002f81a 100644 --- a/trunk/arch/powerpc/kernel/misc_64.S +++ b/trunk/arch/powerpc/kernel/misc_64.S @@ -39,7 +39,7 @@ _GLOBAL(reloc_offset) mflr r0 bl 1f 1: mflr r3 - LOAD_REG_IMMEDIATE(r4,1b) + LOADADDR(r4,1b) subf r3,r4,r3 mtlr r0 blr @@ -51,7 +51,7 @@ _GLOBAL(add_reloc_offset) mflr r0 bl 1f 1: mflr r5 - LOAD_REG_IMMEDIATE(r4,1b) + LOADADDR(r4,1b) subf r5,r4,r5 add r3,r3,r5 mtlr r0 @@ -498,15 +498,15 @@ _GLOBAL(identify_cpu) */ _GLOBAL(do_cpu_ftr_fixups) /* Get CPU 0 features */ - LOAD_REG_IMMEDIATE(r6,cur_cpu_spec) + LOADADDR(r6,cur_cpu_spec) sub r6,r6,r3 ld r4,0(r6) sub r4,r4,r3 ld r4,CPU_SPEC_FEATURES(r4) /* Get the fixup table */ - LOAD_REG_IMMEDIATE(r6,__start___ftr_fixup) + LOADADDR(r6,__start___ftr_fixup) sub r6,r6,r3 - LOAD_REG_IMMEDIATE(r7,__stop___ftr_fixup) + LOADADDR(r7,__stop___ftr_fixup) sub r7,r7,r3 /* Do the fixup */ 1: cmpld r6,r7 diff --git a/trunk/arch/powerpc/kernel/paca.c b/trunk/arch/powerpc/kernel/paca.c index 5d1b708086bd..999bdd816769 100644 --- a/trunk/arch/powerpc/kernel/paca.c +++ b/trunk/arch/powerpc/kernel/paca.c @@ -25,28 +25,6 @@ * field correctly */ extern unsigned long __toc_start; -/* - * iSeries structure which the hypervisor knows about - this structure - * should not cross a page boundary. The vpa_init/register_vpa call - * is now known to fail if the lppaca structure crosses a page - * boundary. The lppaca is also used on POWER5 pSeries boxes. The - * lppaca is 640 bytes long, and cannot readily change since the - * hypervisor knows its layout, so a 1kB alignment will suffice to - * ensure that it doesn't cross a page boundary. - */ -struct lppaca lppaca[] = { - [0 ... (NR_CPUS-1)] = { - .desc = 0xd397d781, /* "LpPa" */ - .size = sizeof(struct lppaca), - .dyn_proc_status = 2, - .decr_val = 0x00ff0000, - .fpregs_in_use = 1, - .end_of_quantum = 0xfffffffffffffffful, - .slb_count = 64, - .vmxregs_in_use = 0, - }, -}; - /* The Paca is an array with one entry per processor. Each contains an * lppaca, which contains the information shared between the * hypervisor and Linux. @@ -57,17 +35,27 @@ struct lppaca lppaca[] = { * processor (not thread). */ #define PACA_INIT_COMMON(number, start, asrr, asrv) \ - .lppaca_ptr = &lppaca[number], \ .lock_token = 0x8000, \ .paca_index = (number), /* Paca Index */ \ .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ .stab_real = (asrr), /* Real pointer to segment table */ \ .stab_addr = (asrv), /* Virt pointer to segment table */ \ .cpu_start = (start), /* Processor start */ \ - .hw_cpu_id = 0xffff, + .hw_cpu_id = 0xffff, \ + .lppaca = { \ + .desc = 0xd397d781, /* "LpPa" */ \ + .size = sizeof(struct lppaca), \ + .dyn_proc_status = 2, \ + .decr_val = 0x00ff0000, \ + .fpregs_in_use = 1, \ + .end_of_quantum = 0xfffffffffffffffful, \ + .slb_count = 64, \ + .vmxregs_in_use = 0, \ + }, \ #ifdef CONFIG_PPC_ISERIES #define PACA_INIT_ISERIES(number) \ + .lppaca_ptr = &paca[number].lppaca, \ .reg_save_ptr = &iseries_reg_save[number], #define PACA_INIT(number) \ diff --git a/trunk/arch/powerpc/kernel/ppc_ksyms.c b/trunk/arch/powerpc/kernel/ppc_ksyms.c index d9a459c144d8..16d9a904f3cb 100644 --- a/trunk/arch/powerpc/kernel/ppc_ksyms.c +++ b/trunk/arch/powerpc/kernel/ppc_ksyms.c @@ -230,7 +230,8 @@ EXPORT_SYMBOL(__down_interruptible); EXPORT_SYMBOL(cpm_install_handler); EXPORT_SYMBOL(cpm_free_handler); #endif /* CONFIG_8xx */ -#if defined(CONFIG_8xx) || defined(CONFIG_40x) +#if defined(CONFIG_8xx) || defined(CONFIG_40x) || defined(CONFIG_85xx) ||\ + defined(CONFIG_83xx) EXPORT_SYMBOL(__res); #endif diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index d50c8df0183e..02e2115323e4 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -1627,11 +1627,6 @@ static void of_node_release(struct kref *kref) kfree(prop->value); kfree(prop); prop = next; - - if (!prop) { - prop = node->deadprops; - node->deadprops = NULL; - } } kfree(node->intrs); kfree(node->full_name); @@ -1779,32 +1774,22 @@ static int __init prom_reconfig_setup(void) __initcall(prom_reconfig_setup); #endif -struct property *of_find_property(struct device_node *np, const char *name, - int *lenp) +/* + * Find a property with a given name for a given node + * and return the value. + */ +unsigned char *get_property(struct device_node *np, const char *name, + int *lenp) { struct property *pp; - read_lock(&devtree_lock); for (pp = np->properties; pp != 0; pp = pp->next) if (strcmp(pp->name, name) == 0) { if (lenp != 0) *lenp = pp->length; - break; + return pp->value; } - read_unlock(&devtree_lock); - - return pp; -} - -/* - * Find a property with a given name for a given node - * and return the value. - */ -unsigned char *get_property(struct device_node *np, const char *name, - int *lenp) -{ - struct property *pp = of_find_property(np,name,lenp); - return pp ? pp->value : NULL; + return NULL; } EXPORT_SYMBOL(get_property); @@ -1838,82 +1823,4 @@ int prom_add_property(struct device_node* np, struct property* prop) return 0; } -/* - * Remove a property from a node. Note that we don't actually - * remove it, since we have given out who-knows-how-many pointers - * to the data using get-property. Instead we just move the property - * to the "dead properties" list, so it won't be found any more. - */ -int prom_remove_property(struct device_node *np, struct property *prop) -{ - struct property **next; - int found = 0; - write_lock(&devtree_lock); - next = &np->properties; - while (*next) { - if (*next == prop) { - /* found the node */ - *next = prop->next; - prop->next = np->deadprops; - np->deadprops = prop; - found = 1; - break; - } - next = &(*next)->next; - } - write_unlock(&devtree_lock); - - if (!found) - return -ENODEV; - -#ifdef CONFIG_PROC_DEVICETREE - /* try to remove the proc node as well */ - if (np->pde) - proc_device_tree_remove_prop(np->pde, prop); -#endif /* CONFIG_PROC_DEVICETREE */ - - return 0; -} - -/* - * Update a property in a node. Note that we don't actually - * remove it, since we have given out who-knows-how-many pointers - * to the data using get-property. Instead we just move the property - * to the "dead properties" list, and add the new property to the - * property list - */ -int prom_update_property(struct device_node *np, - struct property *newprop, - struct property *oldprop) -{ - struct property **next; - int found = 0; - - write_lock(&devtree_lock); - next = &np->properties; - while (*next) { - if (*next == oldprop) { - /* found the node */ - newprop->next = oldprop->next; - *next = newprop; - oldprop->next = np->deadprops; - np->deadprops = oldprop; - found = 1; - break; - } - next = &(*next)->next; - } - write_unlock(&devtree_lock); - - if (!found) - return -ENODEV; - -#ifdef CONFIG_PROC_DEVICETREE - /* try to add to proc as well if it was initialized */ - if (np->pde) - proc_device_tree_update_prop(np->pde, newprop, oldprop); -#endif /* CONFIG_PROC_DEVICETREE */ - - return 0; -} diff --git a/trunk/arch/powerpc/kernel/prom_parse.c b/trunk/arch/powerpc/kernel/prom_parse.c index a8099c806150..309ae1d5fa77 100644 --- a/trunk/arch/powerpc/kernel/prom_parse.c +++ b/trunk/arch/powerpc/kernel/prom_parse.c @@ -113,8 +113,7 @@ static unsigned int of_bus_default_get_flags(u32 *addr) static int of_bus_pci_match(struct device_node *np) { - /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */ - return !strcmp(np->type, "pci") || !strcmp(np->type, "vci"); + return !strcmp(np->type, "pci"); } static void of_bus_pci_count_cells(struct device_node *np, diff --git a/trunk/arch/powerpc/kernel/rtas.c b/trunk/arch/powerpc/kernel/rtas.c index 7fe4a5c944c9..4b9cfe4637b1 100644 --- a/trunk/arch/powerpc/kernel/rtas.c +++ b/trunk/arch/powerpc/kernel/rtas.c @@ -36,11 +36,6 @@ struct rtas_t rtas = { .lock = SPIN_LOCK_UNLOCKED }; -struct rtas_suspend_me_data { - long waiting; - struct rtas_args *args; -}; - EXPORT_SYMBOL(rtas); DEFINE_SPINLOCK(rtas_data_buf_lock); @@ -561,80 +556,6 @@ void rtas_os_term(char *str) } while (status == RTAS_BUSY); } -static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; -#ifdef CONFIG_PPC_PSERIES -static void rtas_percpu_suspend_me(void *info) -{ - long rc; - long flags; - struct rtas_suspend_me_data *data = - (struct rtas_suspend_me_data *)info; - - /* - * We use "waiting" to indicate our state. As long - * as it is >0, we are still trying to all join up. - * If it goes to 0, we have successfully joined up and - * one thread got H_Continue. If any error happens, - * we set it to <0. - */ - local_irq_save(flags); - do { - rc = plpar_hcall_norets(H_JOIN); - smp_rmb(); - } while (rc == H_Success && data->waiting > 0); - if (rc == H_Success) - goto out; - - if (rc == H_Continue) { - data->waiting = 0; - rtas_call(ibm_suspend_me_token, 0, 1, - data->args->args); - } else { - data->waiting = -EBUSY; - printk(KERN_ERR "Error on H_Join hypervisor call\n"); - } - -out: - /* before we restore interrupts, make sure we don't - * generate a spurious soft lockup errors - */ - touch_softlockup_watchdog(); - local_irq_restore(flags); - return; -} - -static int rtas_ibm_suspend_me(struct rtas_args *args) -{ - int i; - - struct rtas_suspend_me_data data; - - data.waiting = 1; - data.args = args; - - /* Call function on all CPUs. One of us will make the - * rtas call - */ - if (on_each_cpu(rtas_percpu_suspend_me, &data, 1, 0)) - data.waiting = -EINVAL; - - if (data.waiting != 0) - printk(KERN_ERR "Error doing global join\n"); - - /* Prod each CPU. This won't hurt, and will wake - * anyone we successfully put to sleep with H_Join - */ - for_each_cpu(i) - plpar_hcall_norets(H_PROD, i); - - return data.waiting; -} -#else /* CONFIG_PPC_PSERIES */ -static int rtas_ibm_suspend_me(struct rtas_args *args) -{ - return -ENOSYS; -} -#endif asmlinkage int ppc_rtas(struct rtas_args __user *uargs) { @@ -642,7 +563,6 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) unsigned long flags; char *buff_copy, *errbuf = NULL; int nargs; - int rc; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -661,17 +581,6 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) nargs * sizeof(rtas_arg_t)) != 0) return -EFAULT; - if (args.token == RTAS_UNKNOWN_SERVICE) - return -EINVAL; - - /* Need to handle ibm,suspend_me call specially */ - if (args.token == ibm_suspend_me_token) { - rc = rtas_ibm_suspend_me(&args); - if (rc) - return rc; - goto copy_return; - } - buff_copy = get_errorlog_buffer(); spin_lock_irqsave(&rtas.lock, flags); @@ -695,7 +604,6 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) kfree(buff_copy); } - copy_return: /* Copy out args. */ if (copy_to_user(uargs->args + nargs, args.args + nargs, @@ -767,10 +675,8 @@ void __init rtas_initialize(void) * the stop-self token if any */ #ifdef CONFIG_PPC64 - if (_machine == PLATFORM_PSERIES_LPAR) { + if (_machine == PLATFORM_PSERIES_LPAR) rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); - ibm_suspend_me_token = rtas_token("ibm,suspend-me"); - } #endif rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); diff --git a/trunk/arch/powerpc/kernel/setup-common.c b/trunk/arch/powerpc/kernel/setup-common.c index be12041c0fc5..d5c52fae023a 100644 --- a/trunk/arch/powerpc/kernel/setup-common.c +++ b/trunk/arch/powerpc/kernel/setup-common.c @@ -100,8 +100,7 @@ void machine_shutdown(void) void machine_restart(char *cmd) { machine_shutdown(); - if (ppc_md.restart) - ppc_md.restart(cmd); + ppc_md.restart(cmd); #ifdef CONFIG_SMP smp_send_stop(); #endif @@ -113,8 +112,7 @@ void machine_restart(char *cmd) void machine_power_off(void) { machine_shutdown(); - if (ppc_md.power_off) - ppc_md.power_off(); + ppc_md.power_off(); #ifdef CONFIG_SMP smp_send_stop(); #endif @@ -131,8 +129,7 @@ EXPORT_SYMBOL_GPL(pm_power_off); void machine_halt(void) { machine_shutdown(); - if (ppc_md.halt) - ppc_md.halt(); + ppc_md.halt(); #ifdef CONFIG_SMP smp_send_stop(); #endif diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index c4a294d657b9..56f50e91bddb 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -431,7 +431,7 @@ void timer_interrupt(struct pt_regs * regs) profile_tick(CPU_PROFILING, regs); #ifdef CONFIG_PPC_ISERIES - get_lppaca()->int_dword.fields.decr_int = 0; + get_paca()->lppaca.int_dword.fields.decr_int = 0; #endif while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu))) diff --git a/trunk/arch/powerpc/lib/locks.c b/trunk/arch/powerpc/lib/locks.c index 8362fa272ca5..35bd03c41dd1 100644 --- a/trunk/arch/powerpc/lib/locks.c +++ b/trunk/arch/powerpc/lib/locks.c @@ -28,13 +28,15 @@ void __spin_yield(raw_spinlock_t *lock) { unsigned int lock_value, holder_cpu, yield_count; + struct paca_struct *holder_paca; lock_value = lock->slock; if (lock_value == 0) return; holder_cpu = lock_value & 0xffff; BUG_ON(holder_cpu >= NR_CPUS); - yield_count = lppaca[holder_cpu].yield_count; + holder_paca = &paca[holder_cpu]; + yield_count = holder_paca->lppaca.yield_count; if ((yield_count & 1) == 0) return; /* virtual cpu is currently running */ rmb(); @@ -58,13 +60,15 @@ void __rw_yield(raw_rwlock_t *rw) { int lock_value; unsigned int holder_cpu, yield_count; + struct paca_struct *holder_paca; lock_value = rw->lock; if (lock_value >= 0) return; /* no write lock at present */ holder_cpu = lock_value & 0xffff; BUG_ON(holder_cpu >= NR_CPUS); - yield_count = lppaca[holder_cpu].yield_count; + holder_paca = &paca[holder_cpu]; + yield_count = holder_paca->lppaca.yield_count; if ((yield_count & 1) == 0) return; /* virtual cpu is currently running */ rmb(); diff --git a/trunk/arch/powerpc/oprofile/common.c b/trunk/arch/powerpc/oprofile/common.c index cc2535be3a73..71615eb70b2b 100644 --- a/trunk/arch/powerpc/oprofile/common.c +++ b/trunk/arch/powerpc/oprofile/common.c @@ -140,19 +140,19 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) switch (cur_cpu_spec->oprofile_type) { #ifdef CONFIG_PPC64 - case PPC_OPROFILE_RS64: + case RS64: model = &op_model_rs64; break; - case PPC_OPROFILE_POWER4: + case POWER4: model = &op_model_power4; break; #else - case PPC_OPROFILE_G4: + case G4: model = &op_model_7450; break; #endif #ifdef CONFIG_FSL_BOOKE - case PPC_OPROFILE_BOOKE: + case BOOKE: model = &op_model_fsl_booke; break; #endif diff --git a/trunk/arch/powerpc/platforms/83xx/Kconfig b/trunk/arch/powerpc/platforms/83xx/Kconfig index 7675e675dce1..b20812d460e6 100644 --- a/trunk/arch/powerpc/platforms/83xx/Kconfig +++ b/trunk/arch/powerpc/platforms/83xx/Kconfig @@ -7,7 +7,6 @@ choice config MPC834x_SYS bool "Freescale MPC834x SYS" - select DEFAULT_UIMAGE help This option enables support for the MPC 834x SYS evaluation board. diff --git a/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c b/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c deleted file mode 100644 index 2098dd05a773..000000000000 --- a/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * arch/powerpc/platforms/83xx/mpc834x_sys.c - * - * MPC834x SYS board specific routines - * - * Maintainer: Kumar Gala - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mpc83xx.h" - -#ifndef CONFIG_PCI -unsigned long isa_io_base = 0; -unsigned long isa_mem_base = 0; -#endif - -#ifdef CONFIG_PCI -extern int mpc83xx_pci2_busno; - -static int -mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) -{ - static char pci_irq_table[][4] = - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - { - {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */ - {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */ - {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x13 */ - {0, 0, 0, 0}, - {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x15 */ - {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x16 */ - {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x17 */ - {PIRQB, PIRQC, PIRQD, PIRQA}, /* idsel 0x18 */ - {0, 0, 0, 0}, /* idsel 0x19 */ - {0, 0, 0, 0}, /* idsel 0x20 */ - }; - - const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4; - return PCI_IRQ_TABLE_LOOKUP; -} - -static int -mpc83xx_exclude_device(u_char bus, u_char devfn) -{ - if (bus == 0 && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if (mpc83xx_pci2_busno) - if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; -} -#endif /* CONFIG_PCI */ - -/* ************************************************************************ - * - * Setup the architecture - * - */ -static void __init -mpc834x_sys_setup_arch(void) -{ - struct device_node *np; - - if (ppc_md.progress) - ppc_md.progress("mpc834x_sys_setup_arch()", 0); - - np = of_find_node_by_type(NULL, "cpu"); - if (np != 0) { - unsigned int *fp = (int *) get_property(np, "clock-frequency", NULL); - if (fp != 0) - loops_per_jiffy = *fp / HZ; - else - loops_per_jiffy = 50000000 / HZ; - of_node_put(np); - } - -#ifdef CONFIG_PCI - for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) - add_bridge(np); - - ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = mpc83xx_map_irq; - ppc_md.pci_exclude_device = mpc83xx_exclude_device; -#endif - -#ifdef CONFIG_ROOT_NFS - ROOT_DEV = Root_NFS; -#else - ROOT_DEV = Root_HDA1; -#endif -} - -void __init -mpc834x_sys_init_IRQ(void) -{ - u8 senses[8] = { - 0, /* EXT 0 */ - IRQ_SENSE_LEVEL, /* EXT 1 */ - IRQ_SENSE_LEVEL, /* EXT 2 */ - 0, /* EXT 3 */ -#ifdef CONFIG_PCI - IRQ_SENSE_LEVEL, /* EXT 4 */ - IRQ_SENSE_LEVEL, /* EXT 5 */ - IRQ_SENSE_LEVEL, /* EXT 6 */ - IRQ_SENSE_LEVEL, /* EXT 7 */ -#else - 0, /* EXT 4 */ - 0, /* EXT 5 */ - 0, /* EXT 6 */ - 0, /* EXT 7 */ -#endif - }; - - ipic_init(get_immrbase() + 0x00700, 0, 0, senses, 8); - - /* Initialize the default interrupt mapping priorities, - * in case the boot rom changed something on us. - */ - ipic_set_default_priority(); -} - -#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374) -extern ulong ds1374_get_rtc_time(void); -extern int ds1374_set_rtc_time(ulong); - -static int __init -mpc834x_rtc_hookup(void) -{ - struct timespec tv; - - ppc_md.get_rtc_time = ds1374_get_rtc_time; - ppc_md.set_rtc_time = ds1374_set_rtc_time; - - tv.tv_nsec = 0; - tv.tv_sec = (ppc_md.get_rtc_time)(); - do_settimeofday(&tv); - - return 0; -} -late_initcall(mpc834x_rtc_hookup); -#endif - -static void -mpc83xx_restart(char *cmd) -{ -#define RST_OFFSET 0x00000900 -#define RST_PROT_REG 0x00000018 -#define RST_CTRL_REG 0x0000001c - __be32 __iomem *reg; - - // map reset register space - reg = ioremap(get_immrbase() + 0x900, 0xff); - - local_irq_disable(); - - /* enable software reset "RSTE" */ - out_be32(reg + (RST_PROT_REG >> 2), 0x52535445); - - /* set software hard reset */ - out_be32(reg + (RST_CTRL_REG >> 2), 0x52535445); - for(;;); -} - -static long __init -mpc83xx_time_init(void) -{ -#define SPCR_OFFSET 0x00000110 -#define SPCR_TBEN 0x00400000 - __be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4); - __be32 tmp; - - tmp = in_be32(spcr); - out_be32(spcr, tmp|SPCR_TBEN); - - iounmap(spcr); - - return 0; -} -void __init -platform_init(void) -{ - /* setup the PowerPC module struct */ - ppc_md.setup_arch = mpc834x_sys_setup_arch; - - ppc_md.init_IRQ = mpc834x_sys_init_IRQ; - ppc_md.get_irq = ipic_get_irq; - - ppc_md.restart = mpc83xx_restart; - - ppc_md.time_init = mpc83xx_time_init; - ppc_md.set_rtc_time = NULL; - ppc_md.get_rtc_time = NULL; - ppc_md.calibrate_decr = generic_calibrate_decr; - - ppc_md.progress = udbg_progress; - - if (ppc_md.progress) - ppc_md.progress("mpc834x_sys_init(): exit", 0); - - return; -} - - diff --git a/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.h b/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.h deleted file mode 100644 index e4ca39f6a862..000000000000 --- a/trunk/arch/powerpc/platforms/83xx/mpc834x_sys.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * arch/powerppc/platforms/83xx/mpc834x_sys.h - * - * MPC834X SYS common board definitions - * - * Maintainer: Kumar Gala - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#ifndef __MACH_MPC83XX_SYS_H__ -#define __MACH_MPC83XX_SYS_H__ - -#define PIRQA MPC83xx_IRQ_EXT4 -#define PIRQB MPC83xx_IRQ_EXT5 -#define PIRQC MPC83xx_IRQ_EXT6 -#define PIRQD MPC83xx_IRQ_EXT7 - -#endif /* __MACH_MPC83XX_SYS_H__ */ diff --git a/trunk/arch/powerpc/platforms/83xx/mpc83xx.h b/trunk/arch/powerpc/platforms/83xx/mpc83xx.h deleted file mode 100644 index ce9e66abef24..000000000000 --- a/trunk/arch/powerpc/platforms/83xx/mpc83xx.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __MPC83XX_H__ -#define __MPC83XX_H__ - -#include -#include - -/* - * Declaration for the various functions exported by the - * mpc83xx_* files. Mostly for use by mpc83xx_setup - */ - -extern int add_bridge(struct device_node *dev); - -#endif /* __MPC83XX_H__ */ diff --git a/trunk/arch/powerpc/platforms/83xx/pci.c b/trunk/arch/powerpc/platforms/83xx/pci.c deleted file mode 100644 index 469cdacc5bd4..000000000000 --- a/trunk/arch/powerpc/platforms/83xx/pci.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * FSL SoC setup code - * - * Maintained by Kumar Gala (see MAINTAINERS for contact information) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#undef DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -int mpc83xx_pci2_busno; - -#ifdef CONFIG_PCI -int __init add_bridge(struct device_node *dev) -{ - int len; - struct pci_controller *hose; - struct resource rsrc; - int *bus_range; - int primary = 1, has_address = 0; - phys_addr_t immr = get_immrbase(); - - DBG("Adding PCI host bridge %s\n", dev->full_name); - - /* Fetch host bridge registers address */ - has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); - - /* Get bus range if any */ - bus_range = (int *) get_property(dev, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); - } - - hose = pcibios_alloc_controller(); - if (!hose) - return -ENOMEM; - hose->arch_data = dev; - hose->set_cfg_type = 1; - - hose->first_busno = bus_range ? bus_range[0] : 0; - hose->last_busno = bus_range ? bus_range[1] : 0xff; - - /* MPC83xx supports up to two host controllers one at 0x8500 from immrbar - * the other at 0x8600, we consider the 0x8500 the primary controller - */ - /* PCI 1 */ - if ((rsrc.start & 0xfffff) == 0x8500) { - setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304); - } - /* PCI 2*/ - if ((rsrc.start & 0xfffff) == 0x8600) { - setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384); - primary = 0; - hose->bus_offset = hose->first_busno; - mpc83xx_pci2_busno = hose->first_busno; - } - - printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. " - "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); - - DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", - hose, hose->cfg_addr, hose->cfg_data); - - /* Interpret the "ranges" property */ - /* This also maps the I/O region and sets isa_io/mem_base */ - pci_process_bridge_OF_ranges(hose, dev, primary); - - return 0; -} - -#endif diff --git a/trunk/arch/powerpc/platforms/chrp/pci.c b/trunk/arch/powerpc/platforms/chrp/pci.c index 00c52f27ef4f..82c429d487f3 100644 --- a/trunk/arch/powerpc/platforms/chrp/pci.c +++ b/trunk/arch/powerpc/platforms/chrp/pci.c @@ -135,13 +135,12 @@ int __init hydra_init(void) { struct device_node *np; - struct resource r; np = find_devices("mac-io"); - if (np == NULL || of_address_to_resource(np, 0, &r)) + if (np == NULL || np->n_addrs == 0) return 0; - Hydra = ioremap(r.start, r.end-r.start); - printk("Hydra Mac I/O at %lx\n", r.start); + Hydra = ioremap(np->addrs[0].address, np->addrs[0].size); + printk("Hydra Mac I/O at %lx\n", np->addrs[0].address); printk("Hydra Feature_Control was %x", in_le32(&Hydra->Feature_Control)); out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | @@ -178,24 +177,18 @@ setup_python(struct pci_controller *hose, struct device_node *dev) { u32 __iomem *reg; u32 val; - struct resource r; + unsigned long addr = dev->addrs[0].address; - if (of_address_to_resource(dev, 0, &r)) { - printk(KERN_ERR "No address for Python PCI controller\n"); - return; - } + setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010); /* Clear the magic go-slow bit */ - reg = ioremap(r.start + 0xf6000, 0x40); - BUG_ON(!reg); + reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40); val = in_be32(®[12]); if (val & PRG_CL_RESET_VALID) { out_be32(®[12], val & ~PRG_CL_RESET_VALID); in_be32(®[12]); } iounmap(reg); - - setup_indirect_pci(hose, r.start + 0xf8000, r.start + 0xf8010); } /* Marvell Discovery II based Pegasos 2 */ @@ -225,7 +218,7 @@ chrp_find_bridges(void) char *model, *machine; int is_longtrail = 0, is_mot = 0, is_pegasos = 0; struct device_node *root = find_path_device("/"); - struct resource r; + /* * The PCI host bridge nodes on some machines don't have * properties to adequately identify them, so we have to @@ -245,7 +238,7 @@ chrp_find_bridges(void) continue; ++index; /* The GG2 bridge on the LongTrail doesn't have an address */ - if (of_address_to_resource(dev, 0, &r) && !is_longtrail) { + if (dev->n_addrs < 1 && !is_longtrail) { printk(KERN_WARNING "Can't use %s: no address\n", dev->full_name); continue; @@ -262,8 +255,8 @@ chrp_find_bridges(void) printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); printk(" controlled by %s", dev->type); - if (!is_longtrail) - printk(" at %lx", r.start); + if (dev->n_addrs > 0) + printk(" at %lx", dev->addrs[0].address); printk("\n"); hose = pcibios_alloc_controller(); diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 2dc87aa5962f..4ec8ba737e7d 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -352,10 +352,9 @@ static void __init chrp_find_openpic(void) opaddr = opprop[na-1]; /* assume 32-bit */ oplen /= na * sizeof(unsigned int); } else { - struct resource r; - if (of_address_to_resource(np, 0, &r)) + if (np->n_addrs == 0) return; - opaddr = r.start; + opaddr = np->addrs[0].address; oplen = 0; } @@ -378,7 +377,7 @@ static void __init chrp_find_openpic(void) */ if (oplen < len) { printk(KERN_ERR "Insufficient addresses for distributed" - " OpenPIC (%d < %d)\n", oplen, len); + " OpenPIC (%d < %d)\n", np->n_addrs, len); len = oplen; } diff --git a/trunk/arch/powerpc/platforms/chrp/time.c b/trunk/arch/powerpc/platforms/chrp/time.c index 36a0f97bb7b1..737ee5d9f0aa 100644 --- a/trunk/arch/powerpc/platforms/chrp/time.c +++ b/trunk/arch/powerpc/platforms/chrp/time.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -38,16 +37,14 @@ static int nvram_data = NVRAM_DATA; long __init chrp_time_init(void) { struct device_node *rtcs; - struct resource r; int base; rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); if (rtcs == NULL) rtcs = find_compatible_devices("rtc", "ds1385-rtc"); - if (rtcs == NULL || of_address_to_resource(rtcs, 0, &r)) + if (rtcs == NULL || rtcs->addrs == NULL) return 0; - - base = r.start; + base = rtcs->addrs[0].address; nvram_as1 = 0; nvram_as0 = base; nvram_data = base + 1; diff --git a/trunk/arch/powerpc/platforms/iseries/irq.c b/trunk/arch/powerpc/platforms/iseries/irq.c index be3fbfc24e6c..83442ea77476 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.c +++ b/trunk/arch/powerpc/platforms/iseries/irq.c @@ -334,12 +334,14 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, */ int iSeries_get_irq(struct pt_regs *regs) { + struct paca_struct *lpaca; /* -2 means ignore this interrupt */ int irq = -2; + lpaca = get_paca(); #ifdef CONFIG_SMP - if (get_lppaca()->int_dword.fields.ipi_cnt) { - get_lppaca()->int_dword.fields.ipi_cnt = 0; + if (lpaca->lppaca.int_dword.fields.ipi_cnt) { + lpaca->lppaca.int_dword.fields.ipi_cnt = 0; iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ diff --git a/trunk/arch/powerpc/platforms/iseries/misc.S b/trunk/arch/powerpc/platforms/iseries/misc.S index 7641fc7e550a..dfe7aa1ba098 100644 --- a/trunk/arch/powerpc/platforms/iseries/misc.S +++ b/trunk/arch/powerpc/platforms/iseries/misc.S @@ -44,8 +44,7 @@ _GLOBAL(local_irq_restore) /* Check pending interrupts */ /* A decrementer, IPI or PMC interrupt may have occurred * while we were in the hypervisor (which enables) */ - ld r4,PACALPPACAPTR(r13) - ld r4,LPPACAANYINT(r4) + ld r4,PACALPPACA+LPPACAANYINT(r13) cmpdi r4,0 beqlr diff --git a/trunk/arch/powerpc/platforms/iseries/setup.c b/trunk/arch/powerpc/platforms/iseries/setup.c index 3f8790146b00..c6bbe5c25107 100644 --- a/trunk/arch/powerpc/platforms/iseries/setup.c +++ b/trunk/arch/powerpc/platforms/iseries/setup.c @@ -538,7 +538,7 @@ static unsigned long __init build_iSeries_Memory_Map(void) */ static void __init iSeries_setup_arch(void) { - if (get_lppaca()->shared_proc) { + if (get_paca()->lppaca.shared_proc) { ppc_md.idle_loop = iseries_shared_idle; printk(KERN_INFO "Using shared processor idle loop\n"); } else { @@ -647,7 +647,7 @@ static void yield_shared_processor(void) * The decrementer stops during the yield. Force a fake decrementer * here and let the timer_interrupt code sort out the actual time. */ - get_lppaca()->int_dword.fields.decr_int = 1; + get_paca()->lppaca.int_dword.fields.decr_int = 1; process_iSeries_events(); } @@ -883,7 +883,7 @@ void dt_cpus(struct iseries_flat_dt *dt) pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); for (i = 0; i < NR_CPUS; i++) { - if (lppaca[i].dyn_proc_status >= 2) + if (paca[i].lppaca.dyn_proc_status >= 2) continue; snprintf(p, 32 - (p - buf), "@%d", i); @@ -891,7 +891,7 @@ void dt_cpus(struct iseries_flat_dt *dt) dt_prop_str(dt, "device_type", "cpu"); - index = lppaca[i].dyn_hv_phys_proc_index; + index = paca[i].lppaca.dyn_hv_phys_proc_index; d = &xIoHriProcessorVpd[index]; dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); diff --git a/trunk/arch/powerpc/platforms/iseries/smp.c b/trunk/arch/powerpc/platforms/iseries/smp.c index 6f9d407a709f..fcb094ec6aec 100644 --- a/trunk/arch/powerpc/platforms/iseries/smp.c +++ b/trunk/arch/powerpc/platforms/iseries/smp.c @@ -91,7 +91,7 @@ static void smp_iSeries_kick_cpu(int nr) BUG_ON((nr < 0) || (nr >= NR_CPUS)); /* Verify that our partition has a processor nr */ - if (lppaca[nr].dyn_proc_status >= 2) + if (paca[nr].lppaca.dyn_proc_status >= 2) return; /* The processor is currently spinning, waiting diff --git a/trunk/arch/powerpc/platforms/pseries/lpar.c b/trunk/arch/powerpc/platforms/pseries/lpar.c index 8952528d31ac..1fe445ab78a6 100644 --- a/trunk/arch/powerpc/platforms/pseries/lpar.c +++ b/trunk/arch/powerpc/platforms/pseries/lpar.c @@ -254,11 +254,11 @@ void __init find_udbg_vterm(void) void vpa_init(int cpu) { int hwcpu = get_hard_smp_processor_id(cpu); - unsigned long vpa = __pa(&lppaca[cpu]); + unsigned long vpa = __pa(&paca[cpu].lppaca); long ret; if (cpu_has_feature(CPU_FTR_ALTIVEC)) - lppaca[cpu].vmxregs_in_use = 1; + paca[cpu].lppaca.vmxregs_in_use = 1; ret = register_vpa(hwcpu, vpa); diff --git a/trunk/arch/powerpc/platforms/pseries/reconfig.c b/trunk/arch/powerpc/platforms/pseries/reconfig.c index 86cfa6ecdcf3..d8864164dbe8 100644 --- a/trunk/arch/powerpc/platforms/pseries/reconfig.c +++ b/trunk/arch/powerpc/platforms/pseries/reconfig.c @@ -350,100 +350,6 @@ static int do_remove_node(char *buf) return rv; } -static char *parse_node(char *buf, size_t bufsize, struct device_node **npp) -{ - char *handle_str; - phandle handle; - *npp = NULL; - - handle_str = buf; - - buf = strchr(buf, ' '); - if (!buf) - return NULL; - *buf = '\0'; - buf++; - - handle = simple_strtoul(handle_str, NULL, 10); - - *npp = of_find_node_by_phandle(handle); - return buf; -} - -static int do_add_property(char *buf, size_t bufsize) -{ - struct property *prop = NULL; - struct device_node *np; - unsigned char *value; - char *name, *end; - int length; - end = buf + bufsize; - buf = parse_node(buf, bufsize, &np); - - if (!np) - return -ENODEV; - - if (parse_next_property(buf, end, &name, &length, &value) == NULL) - return -EINVAL; - - prop = new_property(name, length, value, NULL); - if (!prop) - return -ENOMEM; - - prom_add_property(np, prop); - - return 0; -} - -static int do_remove_property(char *buf, size_t bufsize) -{ - struct device_node *np; - char *tmp; - struct property *prop; - buf = parse_node(buf, bufsize, &np); - - if (!np) - return -ENODEV; - - tmp = strchr(buf,' '); - if (tmp) - *tmp = '\0'; - - if (strlen(buf) == 0) - return -EINVAL; - - prop = of_find_property(np, buf, NULL); - - return prom_remove_property(np, prop); -} - -static int do_update_property(char *buf, size_t bufsize) -{ - struct device_node *np; - unsigned char *value; - char *name, *end; - int length; - struct property *newprop, *oldprop; - buf = parse_node(buf, bufsize, &np); - end = buf + bufsize; - - if (!np) - return -ENODEV; - - if (parse_next_property(buf, end, &name, &length, &value) == NULL) - return -EINVAL; - - newprop = new_property(name, length, value, NULL); - if (!newprop) - return -ENOMEM; - - oldprop = of_find_property(np, name,NULL); - if (!oldprop) - return -ENODEV; - - return prom_update_property(np, newprop, oldprop); -} - /** * ofdt_write - perform operations on the Open Firmware device tree * @@ -486,12 +392,6 @@ static ssize_t ofdt_write(struct file *file, const char __user *buf, size_t coun rv = do_add_node(tmp, count - (tmp - kbuf)); else if (!strcmp(kbuf, "remove_node")) rv = do_remove_node(tmp); - else if (!strcmp(kbuf, "add_property")) - rv = do_add_property(tmp, count - (tmp - kbuf)); - else if (!strcmp(kbuf, "remove_property")) - rv = do_remove_property(tmp, count - (tmp - kbuf)); - else if (!strcmp(kbuf, "update_property")) - rv = do_update_property(tmp, count - (tmp - kbuf)); else rv = -EINVAL; out: diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index da6cebaf72cd..68b7f086d63d 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -190,7 +190,7 @@ static void pseries_lpar_enable_pmcs(void) /* instruct hypervisor to maintain PMCs */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) - get_lppaca()->pmcregs_in_use = 1; + get_paca()->lppaca.pmcregs_in_use = 1; } static void __init pSeries_setup_arch(void) @@ -234,7 +234,7 @@ static void __init pSeries_setup_arch(void) /* Choose an idle loop */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) { vpa_init(boot_cpuid); - if (get_lppaca()->shared_proc) { + if (get_paca()->lppaca.shared_proc) { printk(KERN_INFO "Using shared processor idle loop\n"); ppc_md.idle_loop = pseries_shared_idle; } else { @@ -444,10 +444,10 @@ DECLARE_PER_CPU(unsigned long, smt_snooze_delay); static inline void dedicated_idle_sleep(unsigned int cpu) { - struct lppaca *plppaca = &lppaca[cpu ^ 1]; + struct paca_struct *ppaca = &paca[cpu ^ 1]; /* Only sleep if the other thread is not idle */ - if (!(plppaca->idle)) { + if (!(ppaca->lppaca.idle)) { local_irq_disable(); /* @@ -480,6 +480,7 @@ static inline void dedicated_idle_sleep(unsigned int cpu) static void pseries_dedicated_idle(void) { + struct paca_struct *lpaca = get_paca(); unsigned int cpu = smp_processor_id(); unsigned long start_snooze; unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); @@ -490,7 +491,7 @@ static void pseries_dedicated_idle(void) * Indicate to the HV that we are idle. Now would be * a good time to find other work to dispatch. */ - get_lppaca()->idle = 1; + lpaca->lppaca.idle = 1; if (!need_resched()) { start_snooze = get_tb() + @@ -517,7 +518,7 @@ static void pseries_dedicated_idle(void) HMT_medium(); } - get_lppaca()->idle = 0; + lpaca->lppaca.idle = 0; ppc64_runlatch_on(); preempt_enable_no_resched(); @@ -531,6 +532,7 @@ static void pseries_dedicated_idle(void) static void pseries_shared_idle(void) { + struct paca_struct *lpaca = get_paca(); unsigned int cpu = smp_processor_id(); while (1) { @@ -538,7 +540,7 @@ static void pseries_shared_idle(void) * Indicate to the HV that we are idle. Now would be * a good time to find other work to dispatch. */ - get_lppaca()->idle = 1; + lpaca->lppaca.idle = 1; while (!need_resched() && !cpu_is_offline(cpu)) { local_irq_disable(); @@ -562,7 +564,7 @@ static void pseries_shared_idle(void) HMT_medium(); } - get_lppaca()->idle = 0; + lpaca->lppaca.idle = 0; ppc64_runlatch_on(); preempt_enable_no_resched(); @@ -586,7 +588,7 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) { /* Don't risk a hypervisor call if we're crashing */ if (!crash_shutdown) { - unsigned long vpa = __pa(get_lppaca()); + unsigned long vpa = __pa(&get_paca()->lppaca); if (unregister_vpa(hard_smp_processor_id(), vpa)) { printk("VPA deregistration of cpu %u (hw_cpu_id %d) " diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index 4c2b356774ea..0ae841347a09 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -7,4 +7,3 @@ obj-$(CONFIG_40x) += dcr.o obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_PPC_83xx) += ipic.o -obj-$(CONFIG_FSL_SOC) += fsl_soc.o diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c deleted file mode 100644 index 064c9de47732..000000000000 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * FSL SoC setup code - * - * Maintained by Kumar Gala (see MAINTAINERS for contact information) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static phys_addr_t immrbase = -1; - -phys_addr_t get_immrbase(void) -{ - struct device_node *soc; - - if (immrbase != -1) - return immrbase; - - soc = of_find_node_by_type(NULL, "soc"); - if (soc != 0) { - unsigned int size; - void *prop = get_property(soc, "reg", &size); - immrbase = of_translate_address(soc, prop); - of_node_put(soc); - }; - - return immrbase; -} -EXPORT_SYMBOL(get_immrbase); - -static const char * gfar_tx_intr = "tx"; -static const char * gfar_rx_intr = "rx"; -static const char * gfar_err_intr = "error"; - -static int __init gfar_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *mdio_dev, *gfar_dev; - struct resource res; - int ret; - - for (np = NULL, i = 0; (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; i++) { - int k; - struct device_node *child = NULL; - struct gianfar_mdio_data mdio_data; - - memset(&res, 0, sizeof(res)); - memset(&mdio_data, 0, sizeof(mdio_data)); - - ret = of_address_to_resource(np, 0, &res); - if (ret) - goto mdio_err; - - mdio_dev = platform_device_register_simple("fsl-gianfar_mdio", res.start, &res, 1); - if (IS_ERR(mdio_dev)) { - ret = PTR_ERR(mdio_dev); - goto mdio_err; - } - - for (k = 0; k < 32; k++) - mdio_data.irq[k] = -1; - - while ((child = of_get_next_child(np, child)) != NULL) { - if (child->n_intrs) { - u32 *id = (u32 *) get_property(child, "reg", NULL); - mdio_data.irq[*id] = child->intrs[0].line; - } - } - - ret = platform_device_add_data(mdio_dev, &mdio_data, sizeof(struct gianfar_mdio_data)); - if (ret) - goto mdio_unreg; - } - - for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; i++) { - struct resource r[4]; - struct device_node *phy, *mdio; - struct gianfar_platform_data gfar_data; - unsigned int *id; - char *model; - void *mac_addr; - phandle *ph; - - memset(r, 0, sizeof(r)); - memset(&gfar_data, 0, sizeof(gfar_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto gfar_err; - - r[1].start = np->intrs[0].line; - r[1].end = np->intrs[0].line; - r[1].flags = IORESOURCE_IRQ; - - model = get_property(np, "model", NULL); - - /* If we aren't the FEC we have multiple interrupts */ - if (model && strcasecmp(model, "FEC")) { - r[1].name = gfar_tx_intr; - - r[2].name = gfar_rx_intr; - r[2].start = np->intrs[1].line; - r[2].end = np->intrs[1].line; - r[2].flags = IORESOURCE_IRQ; - - r[3].name = gfar_err_intr; - r[3].start = np->intrs[2].line; - r[3].end = np->intrs[2].line; - r[3].flags = IORESOURCE_IRQ; - } - - gfar_dev = platform_device_register_simple("fsl-gianfar", i, &r[0], np->n_intrs + 1); - - if (IS_ERR(gfar_dev)) { - ret = PTR_ERR(gfar_dev); - goto gfar_err; - } - - mac_addr = get_property(np, "address", NULL); - memcpy(gfar_data.mac_addr, mac_addr, 6); - - if (model && !strcasecmp(model, "TSEC")) - gfar_data.device_flags = - FSL_GIANFAR_DEV_HAS_GIGABIT | - FSL_GIANFAR_DEV_HAS_COALESCE | - FSL_GIANFAR_DEV_HAS_RMON | - FSL_GIANFAR_DEV_HAS_MULTI_INTR; - if (model && !strcasecmp(model, "eTSEC")) - gfar_data.device_flags = - FSL_GIANFAR_DEV_HAS_GIGABIT | - FSL_GIANFAR_DEV_HAS_COALESCE | - FSL_GIANFAR_DEV_HAS_RMON | - FSL_GIANFAR_DEV_HAS_MULTI_INTR | - FSL_GIANFAR_DEV_HAS_CSUM | - FSL_GIANFAR_DEV_HAS_VLAN | - FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; - - ph = (phandle *) get_property(np, "phy-handle", NULL); - phy = of_find_node_by_phandle(*ph); - - if (phy == NULL) { - ret = -ENODEV; - goto gfar_unreg; - } - - mdio = of_get_parent(phy); - - id = (u32 *) get_property(phy, "reg", NULL); - ret = of_address_to_resource(mdio, 0, &res); - if (ret) { - of_node_put(phy); - of_node_put(mdio); - goto gfar_unreg; - } - - gfar_data.phy_id = *id; - gfar_data.bus_id = res.start; - - of_node_put(phy); - of_node_put(mdio); - - ret = platform_device_add_data(gfar_dev, &gfar_data, sizeof(struct gianfar_platform_data)); - if (ret) - goto gfar_unreg; - } - - return 0; - -mdio_unreg: - platform_device_unregister(mdio_dev); -mdio_err: - return ret; - -gfar_unreg: - platform_device_unregister(gfar_dev); -gfar_err: - return ret; -} -arch_initcall(gfar_of_init); - -static int __init fsl_i2c_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *i2c_dev; - int ret; - - for (np = NULL, i = 0; (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL; i++) { - struct resource r[2]; - struct fsl_i2c_platform_data i2c_data; - unsigned char * flags = NULL; - - memset(&r, 0, sizeof(r)); - memset(&i2c_data, 0, sizeof(i2c_data)); - - ret = of_address_to_resource(np, 0, &r[0]); - if (ret) - goto i2c_err; - - r[1].start = np->intrs[0].line; - r[1].end = np->intrs[0].line; - r[1].flags = IORESOURCE_IRQ; - - i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); - if (IS_ERR(i2c_dev)) { - ret = PTR_ERR(i2c_dev); - goto i2c_err; - } - - i2c_data.device_flags = 0; - flags = get_property(np, "dfsrr", NULL); - if (flags) - i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR; - - flags = get_property(np, "fsl5200-clocking", NULL); - if (flags) - i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200; - - ret = platform_device_add_data(i2c_dev, &i2c_data, sizeof(struct fsl_i2c_platform_data)); - if (ret) - goto i2c_unreg; - } - - return 0; - -i2c_unreg: - platform_device_unregister(i2c_dev); -i2c_err: - return ret; -} -arch_initcall(fsl_i2c_of_init); - -#ifdef CONFIG_PPC_83xx -static int __init mpc83xx_wdt_init(void) -{ - struct resource r; - struct device_node *soc, *np; - struct platform_device *dev; - unsigned int *freq; - int ret; - - np = of_find_compatible_node(NULL, "watchdog", "mpc83xx_wdt"); - - if (!np) { - ret = -ENODEV; - goto mpc83xx_wdt_nodev; - } - - soc = of_find_node_by_type(NULL, "soc"); - - if (!soc) { - ret = -ENODEV; - goto mpc83xx_wdt_nosoc; - } - - freq = (unsigned int *)get_property(soc, "bus-frequency", NULL); - if (!freq) { - ret = -ENODEV; - goto mpc83xx_wdt_err; - } - - memset(&r, 0, sizeof(r)); - - ret = of_address_to_resource(np, 0, &r); - if (ret) - goto mpc83xx_wdt_err; - - dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1); - if (IS_ERR(dev)) { - ret = PTR_ERR(dev); - goto mpc83xx_wdt_err; - } - - ret = platform_device_add_data(dev, freq, sizeof(int)); - if (ret) - goto mpc83xx_wdt_unreg; - - of_node_put(soc); - of_node_put(np); - - return 0; - -mpc83xx_wdt_unreg: - platform_device_unregister(dev); -mpc83xx_wdt_err: - of_node_put(soc); -mpc83xx_wdt_nosoc: - of_node_put(np); -mpc83xx_wdt_nodev: - return ret; -} -arch_initcall(mpc83xx_wdt_init); -#endif diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.h b/trunk/arch/powerpc/sysdev/fsl_soc.h deleted file mode 100644 index c433d3f39edd..000000000000 --- a/trunk/arch/powerpc/sysdev/fsl_soc.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __PPC_FSL_SOC_H -#define __PPC_FSL_SOC_H -#ifdef __KERNEL__ - -extern phys_addr_t get_immrbase(void); - -#endif -#endif diff --git a/trunk/arch/ppc/kernel/head_8xx.S b/trunk/arch/ppc/kernel/head_8xx.S index 3e6ca7f5843f..de0978742221 100644 --- a/trunk/arch/ppc/kernel/head_8xx.S +++ b/trunk/arch/ppc/kernel/head_8xx.S @@ -375,8 +375,6 @@ DataStoreTLBMiss: lis r11, swapper_pg_dir@h ori r11, r11, swapper_pg_dir@l rlwimi r10, r11, 0, 2, 19 - stw r12, 16(r0) - b LoadLargeDTLB 3: lwz r11, 0(r10) /* Get the level 1 entry */ rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ @@ -432,81 +430,6 @@ DataStoreTLBMiss: InstructionTLBError: b InstructionAccess -LoadLargeDTLB: - li r12, 0 - lwz r11, 0(r10) /* Get the level 1 entry */ - rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ - beq 3f /* If zero, don't try to find a pte */ - - /* We have a pte table, so load fetch the pte from the table. - */ - ori r11, r11, 1 /* Set valid bit in physical L2 page */ - DO_8xx_CPU6(0x3b80, r3) - mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ - mfspr r10, SPRN_MD_TWC /* ....and get the pte address */ - lwz r10, 0(r10) /* Get the pte */ - - /* Insert the Guarded flag into the TWC from the Linux PTE. - * It is bit 27 of both the Linux PTE and the TWC (at least - * I got that right :-). It will be better when we can put - * this into the Linux pgd/pmd and load it in the operation - * above. - */ - rlwimi r11, r10, 0, 27, 27 - - rlwimi r12, r10, 0, 0, 9 /* extract phys. addr */ - mfspr r3, SPRN_MD_EPN - rlwinm r3, r3, 0, 0, 9 /* extract virtual address */ - tophys(r3, r3) - cmpw r3, r12 /* only use 8M page if it is a direct - kernel mapping */ - bne 1f - ori r11, r11, MD_PS8MEG - li r12, 1 - b 2f -1: - li r12, 0 /* can't use 8MB TLB, so zero r12. */ -2: - DO_8xx_CPU6(0x3b80, r3) - mtspr SPRN_MD_TWC, r11 - - /* The Linux PTE won't go exactly into the MMU TLB. - * Software indicator bits 21, 22 and 28 must be clear. - * Software indicator bits 24, 25, 26, and 27 must be - * set. All other Linux PTE bits control the behavior - * of the MMU. - */ -3: li r11, 0x00f0 - rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ - cmpwi r12, 1 - bne 4f - ori r10, r10, 0x8 - - mfspr r12, SPRN_MD_EPN - lis r3, 0xff80 /* 10-19 must be clear for 8MB TLB */ - ori r3, r3, 0x0fff - and r12, r3, r12 - DO_8xx_CPU6(0x3780, r3) - mtspr SPRN_MD_EPN, r12 - - lis r3, 0xff80 /* 10-19 must be clear for 8MB TLB */ - ori r3, r3, 0x0fff - and r10, r3, r10 -4: - DO_8xx_CPU6(0x3d80, r3) - mtspr SPRN_MD_RPN, r10 /* Update TLB entry */ - - mfspr r10, SPRN_M_TW /* Restore registers */ - lwz r11, 0(r0) - mtcr r11 - lwz r11, 4(r0) - - lwz r12, 16(r0) -#ifdef CONFIG_8xx_CPU6 - lwz r3, 8(r0) -#endif - rfi - /* This is the data TLB error on the MPC8xx. This could be due to * many reasons, including a dirty update to a pte. We can catch that * one here, but anything else is an error. First, we track down the diff --git a/trunk/arch/ppc/kernel/ppc_ksyms.c b/trunk/arch/ppc/kernel/ppc_ksyms.c index fb0da7c209db..95075f99a6d4 100644 --- a/trunk/arch/ppc/kernel/ppc_ksyms.c +++ b/trunk/arch/ppc/kernel/ppc_ksyms.c @@ -270,6 +270,7 @@ EXPORT_SYMBOL(__delay); EXPORT_SYMBOL(timer_interrupt); EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(tb_ticks_per_jiffy); +EXPORT_SYMBOL(get_wchan); EXPORT_SYMBOL(console_drivers); #ifdef CONFIG_XMON EXPORT_SYMBOL(xmon); diff --git a/trunk/arch/ppc/platforms/83xx/mpc834x_sys.c b/trunk/arch/ppc/platforms/83xx/mpc834x_sys.c index 012e1e652c03..04bdc39bf47b 100644 --- a/trunk/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/trunk/arch/ppc/platforms/83xx/mpc834x_sys.c @@ -51,6 +51,9 @@ #include +static const char *GFAR_PHY_0 = "phy0:0"; +static const char *GFAR_PHY_1 = "phy0:1"; + #ifndef CONFIG_PCI unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; @@ -126,21 +129,20 @@ mpc834x_sys_setup_arch(void) mdata->irq[1] = MPC83xx_IRQ_EXT2; mdata->irq[2] = -1; mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 0; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 1; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } diff --git a/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c b/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c index 2eceb1e6f4eb..c5cde97c6ef0 100644 --- a/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/trunk/arch/ppc/platforms/85xx/mpc8540_ads.c @@ -52,6 +52,10 @@ #include +static const char *GFAR_PHY_0 = "phy0:0"; +static const char *GFAR_PHY_1 = "phy0:1"; +static const char *GFAR_PHY_3 = "phy0:3"; + /* ************************************************************************ * * Setup the architecture @@ -98,29 +102,27 @@ mpc8540ads_setup_arch(void) mdata->irq[2] = -1; mdata->irq[3] = MPC85xx_IRQ_EXT5; mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 0; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 1; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); if (pdata) { pdata->board_flags = 0; - pdata->bus_id = 0; - pdata->phy_id = 3; + pdata->bus_id = GFAR_PHY_3; memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); } diff --git a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c index 442c7ff195d3..8e39a5517092 100644 --- a/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c +++ b/trunk/arch/ppc/platforms/85xx/mpc8560_ads.c @@ -56,6 +56,10 @@ #include +static const char *GFAR_PHY_0 = "phy0:0"; +static const char *GFAR_PHY_1 = "phy0:1"; +static const char *GFAR_PHY_3 = "phy0:3"; + /* ************************************************************************ * * Setup the architecture @@ -95,21 +99,20 @@ mpc8560ads_setup_arch(void) mdata->irq[2] = -1; mdata->irq[3] = MPC85xx_IRQ_EXT5; mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 0; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 1; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } diff --git a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index b332ebae6bd3..2959e3c4083d 100644 --- a/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/trunk/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -395,6 +395,9 @@ mpc85xx_cds_pcibios_fixup(void) TODC_ALLOC(); +static const char *GFAR_PHY_0 = "phy0:0"; +static const char *GFAR_PHY_1 = "phy0:1"; + /* ************************************************************************ * * Setup the architecture @@ -458,37 +461,34 @@ mpc85xx_cds_setup_arch(void) mdata->irq[2] = -1; mdata->irq[3] = -1; mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 0; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 1; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 0; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 1; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } diff --git a/trunk/arch/ppc/platforms/85xx/sbc8560.c b/trunk/arch/ppc/platforms/85xx/sbc8560.c index e777ba824aa9..45a5b81b4ed1 100644 --- a/trunk/arch/ppc/platforms/85xx/sbc8560.c +++ b/trunk/arch/ppc/platforms/85xx/sbc8560.c @@ -91,6 +91,9 @@ sbc8560_early_serial_map(void) } #endif +static const char *GFAR_PHY_25 = "phy0:25"; +static const char *GFAR_PHY_26 = "phy0:26"; + /* ************************************************************************ * * Setup the architecture @@ -133,21 +136,20 @@ sbc8560_setup_arch(void) mdata->irq[25] = MPC85xx_IRQ_EXT6; mdata->irq[26] = MPC85xx_IRQ_EXT7; mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 25; + pdata->bus_id = GFAR_PHY_25; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 26; + pdata->bus_id = GFAR_PHY_26; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } diff --git a/trunk/arch/ppc/platforms/85xx/stx_gp3.c b/trunk/arch/ppc/platforms/85xx/stx_gp3.c index 061bb7cf2d9a..15ce9d070634 100644 --- a/trunk/arch/ppc/platforms/85xx/stx_gp3.c +++ b/trunk/arch/ppc/platforms/85xx/stx_gp3.c @@ -93,6 +93,9 @@ static u8 gp3_openpic_initsenses[] __initdata = { 0x0, /* External 11: */ }; +static const char *GFAR_PHY_2 = "phy0:2"; +static const char *GFAR_PHY_4 = "phy0:4"; + /* * Setup the architecture */ @@ -127,21 +130,20 @@ gp3_setup_arch(void) mdata->irq[2] = MPC85xx_IRQ_EXT5; mdata->irq[4] = MPC85xx_IRQ_EXT5; mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ - pdata->bus_id = 0; - pdata->phy_id = 2; + pdata->bus_id = GFAR_PHY_2; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { /* pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */ - pdata->bus_id = 0; - pdata->phy_id = 4; + pdata->bus_id = GFAR_PHY_4; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } diff --git a/trunk/arch/ppc/platforms/85xx/tqm85xx.c b/trunk/arch/ppc/platforms/85xx/tqm85xx.c index b436f4d0a3fa..c6dfd8f0f9df 100644 --- a/trunk/arch/ppc/platforms/85xx/tqm85xx.c +++ b/trunk/arch/ppc/platforms/85xx/tqm85xx.c @@ -91,6 +91,12 @@ static u_char tqm85xx_openpic_initsenses[] __initdata = { 0x0, /* External 11: */ }; +static const char *GFAR_PHY_0 = "phy0:2"; +static const char *GFAR_PHY_1 = "phy0:1"; +#ifdef CONFIG_MPC8540 +static const char *GFAR_PHY_3 = "phy0:3"; +#endif + /* ************************************************************************ * * Setup the architecture @@ -143,21 +149,20 @@ tqm85xx_setup_arch(void) mdata->irq[2] = -1; mdata->irq[3] = MPC85xx_IRQ_EXT8; mdata->irq[31] = -1; + mdata->paddr += binfo->bi_immr_base; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 2; + pdata->bus_id = GFAR_PHY_0; memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); } pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); if (pdata) { pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = 0; - pdata->phy_id = 1; + pdata->bus_id = GFAR_PHY_1; memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } @@ -165,8 +170,7 @@ tqm85xx_setup_arch(void) pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); if (pdata) { pdata->board_flags = 0; - pdata->bus_id = 0; - pdata->phy_id = 3; + pdata->bus_id = GFAR_PHY_3; memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); } #endif diff --git a/trunk/arch/ppc/syslib/mpc83xx_devices.c b/trunk/arch/ppc/syslib/mpc83xx_devices.c index f9b95de70e23..847df4409982 100644 --- a/trunk/arch/ppc/syslib/mpc83xx_devices.c +++ b/trunk/arch/ppc/syslib/mpc83xx_devices.c @@ -28,6 +28,7 @@ */ struct gianfar_mdio_data mpc83xx_mdio_pdata = { + .paddr = 0x24520, }; static struct gianfar_platform_data mpc83xx_tsec1_pdata = { @@ -225,14 +226,7 @@ struct platform_device ppc_sys_platform_devices[] = { .name = "fsl-gianfar_mdio", .id = 0, .dev.platform_data = &mpc83xx_mdio_pdata, - .num_resources = 1, - .resource = (struct resource[]) { - { - .start = 0x24520, - .end = 0x2453f, - .flags = IORESOURCE_MEM, - }, - }, + .num_resources = 0, }, }; diff --git a/trunk/arch/ppc/syslib/mpc85xx_devices.c b/trunk/arch/ppc/syslib/mpc85xx_devices.c index 00e9b6ff2f6e..69949d255658 100644 --- a/trunk/arch/ppc/syslib/mpc85xx_devices.c +++ b/trunk/arch/ppc/syslib/mpc85xx_devices.c @@ -26,6 +26,7 @@ * what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup */ struct gianfar_mdio_data mpc85xx_mdio_pdata = { + .paddr = MPC85xx_MIIM_OFFSET, }; static struct gianfar_platform_data mpc85xx_tsec1_pdata = { @@ -719,14 +720,7 @@ struct platform_device ppc_sys_platform_devices[] = { .name = "fsl-gianfar_mdio", .id = 0, .dev.platform_data = &mpc85xx_mdio_pdata, - .num_resources = 1, - .resource = (struct resource[]) { - { - .start = 0x24520, - .end = 0x2453f, - .flags = IORESOURCE_MEM, - }, - }, + .num_resources = 0, }, }; diff --git a/trunk/drivers/infiniband/core/cm.c b/trunk/drivers/infiniband/core/cm.c index c06b18102b6a..3a611fe5497e 100644 --- a/trunk/drivers/infiniband/core/cm.c +++ b/trunk/drivers/infiniband/core/cm.c @@ -3163,6 +3163,22 @@ int ib_cm_init_qp_attr(struct ib_cm_id *cm_id, } EXPORT_SYMBOL(ib_cm_init_qp_attr); +static __be64 cm_get_ca_guid(struct ib_device *device) +{ + struct ib_device_attr *device_attr; + __be64 guid; + int ret; + + device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL); + if (!device_attr) + return 0; + + ret = ib_query_device(device, device_attr); + guid = ret ? 0 : device_attr->node_guid; + kfree(device_attr); + return guid; +} + static void cm_add_one(struct ib_device *device) { struct cm_device *cm_dev; @@ -3184,7 +3200,9 @@ static void cm_add_one(struct ib_device *device) return; cm_dev->device = device; - cm_dev->ca_guid = device->node_guid; + cm_dev->ca_guid = cm_get_ca_guid(device); + if (!cm_dev->ca_guid) + goto error1; set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask); for (i = 1; i <= device->phys_port_cnt; i++) { @@ -3199,11 +3217,11 @@ static void cm_add_one(struct ib_device *device) cm_recv_handler, port); if (IS_ERR(port->mad_agent)) - goto error1; + goto error2; ret = ib_modify_port(device, i, 0, &port_modify); if (ret) - goto error2; + goto error3; } ib_set_client_data(device, &cm_client, cm_dev); @@ -3212,9 +3230,9 @@ static void cm_add_one(struct ib_device *device) write_unlock_irqrestore(&cm.device_lock, flags); return; -error2: +error3: ib_unregister_mad_agent(port->mad_agent); -error1: +error2: port_modify.set_port_cap_mask = 0; port_modify.clr_port_cap_mask = IB_PORT_CM_SUP; while (--i) { @@ -3222,6 +3240,7 @@ static void cm_add_one(struct ib_device *device) ib_modify_port(device, port->port_num, 0, &port_modify); ib_unregister_mad_agent(port->mad_agent); } +error1: kfree(cm_dev); } diff --git a/trunk/drivers/infiniband/core/device.c b/trunk/drivers/infiniband/core/device.c index b2f3cb91d9bc..e169e798354b 100644 --- a/trunk/drivers/infiniband/core/device.c +++ b/trunk/drivers/infiniband/core/device.c @@ -38,7 +38,8 @@ #include #include #include -#include + +#include #include "core_priv.h" @@ -56,13 +57,13 @@ static LIST_HEAD(device_list); static LIST_HEAD(client_list); /* - * device_mutex protects access to both device_list and client_list. + * device_sem protects access to both device_list and client_list. * There's no real point to using multiple locks or something fancier * like an rwsem: we always access both lists, and we're always * modifying one list or the other list. In any case this is not a * hot path so there's no point in trying to optimize. */ -static DEFINE_MUTEX(device_mutex); +static DECLARE_MUTEX(device_sem); static int ib_device_check_mandatory(struct ib_device *device) { @@ -220,7 +221,7 @@ int ib_register_device(struct ib_device *device) { int ret; - mutex_lock(&device_mutex); + down(&device_sem); if (strchr(device->name, '%')) { ret = alloc_name(device->name); @@ -258,7 +259,7 @@ int ib_register_device(struct ib_device *device) } out: - mutex_unlock(&device_mutex); + up(&device_sem); return ret; } EXPORT_SYMBOL(ib_register_device); @@ -275,7 +276,7 @@ void ib_unregister_device(struct ib_device *device) struct ib_client_data *context, *tmp; unsigned long flags; - mutex_lock(&device_mutex); + down(&device_sem); list_for_each_entry_reverse(client, &client_list, list) if (client->remove) @@ -283,7 +284,7 @@ void ib_unregister_device(struct ib_device *device) list_del(&device->core_list); - mutex_unlock(&device_mutex); + up(&device_sem); spin_lock_irqsave(&device->client_data_lock, flags); list_for_each_entry_safe(context, tmp, &device->client_data_list, list) @@ -311,14 +312,14 @@ int ib_register_client(struct ib_client *client) { struct ib_device *device; - mutex_lock(&device_mutex); + down(&device_sem); list_add_tail(&client->list, &client_list); list_for_each_entry(device, &device_list, core_list) if (client->add && !add_client_context(device, client)) client->add(device); - mutex_unlock(&device_mutex); + up(&device_sem); return 0; } @@ -338,7 +339,7 @@ void ib_unregister_client(struct ib_client *client) struct ib_device *device; unsigned long flags; - mutex_lock(&device_mutex); + down(&device_sem); list_for_each_entry(device, &device_list, core_list) { if (client->remove) @@ -354,7 +355,7 @@ void ib_unregister_client(struct ib_client *client) } list_del(&client->list); - mutex_unlock(&device_mutex); + up(&device_sem); } EXPORT_SYMBOL(ib_unregister_client); diff --git a/trunk/drivers/infiniband/core/sysfs.c b/trunk/drivers/infiniband/core/sysfs.c index 5982d687a000..1f1743c5c9a3 100644 --- a/trunk/drivers/infiniband/core/sysfs.c +++ b/trunk/drivers/infiniband/core/sysfs.c @@ -445,7 +445,13 @@ static int ib_device_uevent(struct class_device *cdev, char **envp, return -ENOMEM; /* - * It would be nice to pass the node GUID with the event... + * It might be nice to pass the node GUID with the event, but + * right now the only way to get it is to query the device + * provider, and this can crash during device removal because + * we are will be running after driver removal has started. + * We could add a node_guid field to struct ib_device, or we + * could just let userspace read the node GUID from sysfs when + * devices are added. */ envp[i] = NULL; @@ -617,15 +623,21 @@ static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf) static ssize_t show_node_guid(struct class_device *cdev, char *buf) { struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); + struct ib_device_attr attr; + ssize_t ret; if (!ibdev_is_alive(dev)) return -ENODEV; + ret = ib_query_device(dev, &attr); + if (ret) + return ret; + return sprintf(buf, "%04x:%04x:%04x:%04x\n", - be16_to_cpu(((__be16 *) &dev->node_guid)[0]), - be16_to_cpu(((__be16 *) &dev->node_guid)[1]), - be16_to_cpu(((__be16 *) &dev->node_guid)[2]), - be16_to_cpu(((__be16 *) &dev->node_guid)[3])); + be16_to_cpu(((__be16 *) &attr.node_guid)[0]), + be16_to_cpu(((__be16 *) &attr.node_guid)[1]), + be16_to_cpu(((__be16 *) &attr.node_guid)[2]), + be16_to_cpu(((__be16 *) &attr.node_guid)[3])); } static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); diff --git a/trunk/drivers/infiniband/core/ucm.c b/trunk/drivers/infiniband/core/ucm.c index e95c4293a496..6e15787d1de1 100644 --- a/trunk/drivers/infiniband/core/ucm.c +++ b/trunk/drivers/infiniband/core/ucm.c @@ -42,7 +42,6 @@ #include #include #include -#include #include @@ -114,7 +113,7 @@ static struct ib_client ucm_client = { .remove = ib_ucm_remove_one }; -static DEFINE_MUTEX(ctx_id_mutex); +static DECLARE_MUTEX(ctx_id_mutex); static DEFINE_IDR(ctx_id_table); static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES); @@ -122,7 +121,7 @@ static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) { struct ib_ucm_context *ctx; - mutex_lock(&ctx_id_mutex); + down(&ctx_id_mutex); ctx = idr_find(&ctx_id_table, id); if (!ctx) ctx = ERR_PTR(-ENOENT); @@ -130,7 +129,7 @@ static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) ctx = ERR_PTR(-EINVAL); else atomic_inc(&ctx->ref); - mutex_unlock(&ctx_id_mutex); + up(&ctx_id_mutex); return ctx; } @@ -187,9 +186,9 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) if (!result) goto error; - mutex_lock(&ctx_id_mutex); + down(&ctx_id_mutex); result = idr_get_new(&ctx_id_table, ctx, &ctx->id); - mutex_unlock(&ctx_id_mutex); + up(&ctx_id_mutex); } while (result == -EAGAIN); if (result) @@ -551,9 +550,9 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file, err2: ib_destroy_cm_id(ctx->cm_id); err1: - mutex_lock(&ctx_id_mutex); + down(&ctx_id_mutex); idr_remove(&ctx_id_table, ctx->id); - mutex_unlock(&ctx_id_mutex); + up(&ctx_id_mutex); kfree(ctx); return result; } @@ -573,7 +572,7 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file, if (copy_from_user(&cmd, inbuf, sizeof(cmd))) return -EFAULT; - mutex_lock(&ctx_id_mutex); + down(&ctx_id_mutex); ctx = idr_find(&ctx_id_table, cmd.id); if (!ctx) ctx = ERR_PTR(-ENOENT); @@ -581,7 +580,7 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file, ctx = ERR_PTR(-EINVAL); else idr_remove(&ctx_id_table, ctx->id); - mutex_unlock(&ctx_id_mutex); + up(&ctx_id_mutex); if (IS_ERR(ctx)) return PTR_ERR(ctx); @@ -1281,9 +1280,9 @@ static int ib_ucm_close(struct inode *inode, struct file *filp) struct ib_ucm_context, file_list); up(&file->mutex); - mutex_lock(&ctx_id_mutex); + down(&ctx_id_mutex); idr_remove(&ctx_id_table, ctx->id); - mutex_unlock(&ctx_id_mutex); + up(&ctx_id_mutex); ib_destroy_cm_id(ctx->cm_id); ib_ucm_cleanup_events(ctx); diff --git a/trunk/drivers/infiniband/core/uverbs.h b/trunk/drivers/infiniband/core/uverbs.h index f7eecbc6af6c..7114e3fbab00 100644 --- a/trunk/drivers/infiniband/core/uverbs.h +++ b/trunk/drivers/infiniband/core/uverbs.h @@ -41,7 +41,6 @@ #include #include -#include #include #include @@ -89,7 +88,7 @@ struct ib_uverbs_event_file { struct ib_uverbs_file { struct kref ref; - struct mutex mutex; + struct semaphore mutex; struct ib_uverbs_device *device; struct ib_ucontext *ucontext; struct ib_event_handler event_handler; @@ -132,7 +131,7 @@ struct ib_ucq_object { u32 async_events_reported; }; -extern struct mutex ib_uverbs_idr_mutex; +extern struct semaphore ib_uverbs_idr_mutex; extern struct idr ib_uverbs_pd_idr; extern struct idr ib_uverbs_mr_idr; extern struct idr ib_uverbs_mw_idr; diff --git a/trunk/drivers/infiniband/core/uverbs_cmd.c b/trunk/drivers/infiniband/core/uverbs_cmd.c index 407b6284d7d5..a02c5a05c984 100644 --- a/trunk/drivers/infiniband/core/uverbs_cmd.c +++ b/trunk/drivers/infiniband/core/uverbs_cmd.c @@ -67,7 +67,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&file->mutex); + down(&file->mutex); if (file->ucontext) { ret = -EINVAL; @@ -119,7 +119,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, fd_install(resp.async_fd, filp); - mutex_unlock(&file->mutex); + up(&file->mutex); return in_len; @@ -131,7 +131,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, ibdev->dealloc_ucontext(ucontext); err: - mutex_unlock(&file->mutex); + up(&file->mutex); return ret; } @@ -157,7 +157,7 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file, memset(&resp, 0, sizeof resp); resp.fw_ver = attr.fw_ver; - resp.node_guid = file->device->ib_dev->node_guid; + resp.node_guid = attr.node_guid; resp.sys_image_guid = attr.sys_image_guid; resp.max_mr_size = attr.max_mr_size; resp.page_size_cap = attr.page_size_cap; @@ -290,7 +290,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, pd->uobject = uobj; atomic_set(&pd->usecnt, 0); - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); retry: if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) { @@ -314,11 +314,11 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, goto err_idr; } - mutex_lock(&file->mutex); + down(&file->mutex); list_add_tail(&uobj->list, &file->ucontext->pd_list); - mutex_unlock(&file->mutex); + up(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return in_len; @@ -326,7 +326,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_pd_idr, uobj->id); err_up: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); ib_dealloc_pd(pd); err: @@ -346,7 +346,7 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); if (!pd || pd->uobject->context != file->ucontext) @@ -360,14 +360,14 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle); - mutex_lock(&file->mutex); + down(&file->mutex); list_del(&uobj->list); - mutex_unlock(&file->mutex); + up(&file->mutex); kfree(uobj); out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -426,7 +426,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, obj->umem.virt_base = cmd.hca_va; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); if (!pd || pd->uobject->context != file->ucontext) { @@ -476,11 +476,11 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, goto err_idr; } - mutex_lock(&file->mutex); + down(&file->mutex); list_add_tail(&obj->uobject.list, &file->ucontext->mr_list); - mutex_unlock(&file->mutex); + up(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return in_len; @@ -492,7 +492,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, atomic_dec(&pd->usecnt); err_up: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); ib_umem_release(file->device->ib_dev, &obj->umem); @@ -513,7 +513,7 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle); if (!mr || mr->uobject->context != file->ucontext) @@ -527,15 +527,15 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle); - mutex_lock(&file->mutex); + down(&file->mutex); list_del(&memobj->uobject.list); - mutex_unlock(&file->mutex); + up(&file->mutex); ib_umem_release(file->device->ib_dev, &memobj->umem); kfree(memobj); out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -628,7 +628,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, cq->cq_context = ev_file; atomic_set(&cq->usecnt, 0); - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); retry: if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) { @@ -653,11 +653,11 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, goto err_idr; } - mutex_lock(&file->mutex); + down(&file->mutex); list_add_tail(&uobj->uobject.list, &file->ucontext->cq_list); - mutex_unlock(&file->mutex); + up(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return in_len; @@ -665,7 +665,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_cq_idr, uobj->uobject.id); err_up: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); ib_destroy_cq(cq); err: @@ -701,7 +701,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, goto out_wc; } - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); if (!cq || cq->uobject->context != file->ucontext) { ret = -EINVAL; @@ -731,7 +731,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); kfree(resp); out_wc: @@ -750,14 +750,14 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); if (cq && cq->uobject->context == file->ucontext) { ib_req_notify_cq(cq, cmd.solicited_only ? IB_CQ_SOLICITED : IB_CQ_NEXT_COMP); ret = in_len; } - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret; } @@ -779,7 +779,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, memset(&resp, 0, sizeof resp); - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle); if (!cq || cq->uobject->context != file->ucontext) @@ -795,9 +795,9 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle); - mutex_lock(&file->mutex); + down(&file->mutex); list_del(&uobj->uobject.list); - mutex_unlock(&file->mutex); + up(&file->mutex); ib_uverbs_release_ucq(file, ev_file, uobj); @@ -811,7 +811,7 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -845,7 +845,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle); @@ -930,11 +930,11 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, goto err_idr; } - mutex_lock(&file->mutex); + down(&file->mutex); list_add_tail(&uobj->uevent.uobject.list, &file->ucontext->qp_list); - mutex_unlock(&file->mutex); + up(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return in_len; @@ -950,7 +950,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, atomic_dec(&attr.srq->usecnt); err_up: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); kfree(uobj); return ret; @@ -972,7 +972,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, if (!attr) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) { @@ -1033,7 +1033,7 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, ret = in_len; out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); kfree(attr); return ret; @@ -1054,7 +1054,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, memset(&resp, 0, sizeof resp); - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1073,9 +1073,9 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle); - mutex_lock(&file->mutex); + down(&file->mutex); list_del(&uobj->uevent.uobject.list); - mutex_unlock(&file->mutex); + up(&file->mutex); ib_uverbs_release_uevent(file, &uobj->uevent); @@ -1088,7 +1088,7 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1119,7 +1119,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, if (!user_wr) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1224,7 +1224,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); while (wr) { next = wr->next; @@ -1341,7 +1341,7 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file, if (IS_ERR(wr)) return PTR_ERR(wr); - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1362,7 +1362,7 @@ ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); while (wr) { next = wr->next; @@ -1392,7 +1392,7 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file, if (IS_ERR(wr)) return PTR_ERR(wr); - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); if (!srq || srq->uobject->context != file->ucontext) @@ -1413,7 +1413,7 @@ ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); while (wr) { next = wr->next; @@ -1446,7 +1446,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); if (!pd || pd->uobject->context != file->ucontext) { @@ -1498,11 +1498,11 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, goto err_idr; } - mutex_lock(&file->mutex); + down(&file->mutex); list_add_tail(&uobj->list, &file->ucontext->ah_list); - mutex_unlock(&file->mutex); + up(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return in_len; @@ -1513,7 +1513,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, ib_destroy_ah(ah); err_up: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); kfree(uobj); return ret; @@ -1530,7 +1530,7 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); ah = idr_find(&ib_uverbs_ah_idr, cmd.ah_handle); if (!ah || ah->uobject->context != file->ucontext) @@ -1544,14 +1544,14 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_ah_idr, cmd.ah_handle); - mutex_lock(&file->mutex); + down(&file->mutex); list_del(&uobj->list); - mutex_unlock(&file->mutex); + up(&file->mutex); kfree(uobj); out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1569,7 +1569,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1602,7 +1602,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file, kfree(mcast); out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1620,7 +1620,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle); if (!qp || qp->uobject->context != file->ucontext) @@ -1641,7 +1641,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file, } out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1673,7 +1673,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, if (!uobj) return -ENOMEM; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); @@ -1730,11 +1730,11 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, goto err_idr; } - mutex_lock(&file->mutex); + down(&file->mutex); list_add_tail(&uobj->uobject.list, &file->ucontext->srq_list); - mutex_unlock(&file->mutex); + up(&file->mutex); - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return in_len; @@ -1746,7 +1746,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, atomic_dec(&pd->usecnt); err_up: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); kfree(uobj); return ret; @@ -1764,7 +1764,7 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle); if (!srq || srq->uobject->context != file->ucontext) { @@ -1778,7 +1778,7 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file, ret = ib_modify_srq(srq, &attr, cmd.attr_mask); out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } @@ -1796,7 +1796,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); memset(&resp, 0, sizeof resp); @@ -1812,9 +1812,9 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle); - mutex_lock(&file->mutex); + down(&file->mutex); list_del(&uobj->uobject.list); - mutex_unlock(&file->mutex); + up(&file->mutex); ib_uverbs_release_uevent(file, uobj); @@ -1827,7 +1827,7 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, ret = -EFAULT; out: - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return ret ? ret : in_len; } diff --git a/trunk/drivers/infiniband/core/uverbs_main.c b/trunk/drivers/infiniband/core/uverbs_main.c index 96ea79b63df7..81737bd6faea 100644 --- a/trunk/drivers/infiniband/core/uverbs_main.c +++ b/trunk/drivers/infiniband/core/uverbs_main.c @@ -66,7 +66,7 @@ enum { static struct class *uverbs_class; -DEFINE_MUTEX(ib_uverbs_idr_mutex); +DECLARE_MUTEX(ib_uverbs_idr_mutex); DEFINE_IDR(ib_uverbs_pd_idr); DEFINE_IDR(ib_uverbs_mr_idr); DEFINE_IDR(ib_uverbs_mw_idr); @@ -180,7 +180,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, if (!context) return 0; - mutex_lock(&ib_uverbs_idr_mutex); + down(&ib_uverbs_idr_mutex); list_for_each_entry_safe(uobj, tmp, &context->ah_list, list) { struct ib_ah *ah = idr_find(&ib_uverbs_ah_idr, uobj->id); @@ -250,7 +250,7 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, kfree(uobj); } - mutex_unlock(&ib_uverbs_idr_mutex); + up(&ib_uverbs_idr_mutex); return context->device->dealloc_ucontext(context); } @@ -653,7 +653,7 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) file->ucontext = NULL; file->async_file = NULL; kref_init(&file->ref); - mutex_init(&file->mutex); + init_MUTEX(&file->mutex); filp->private_data = file; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_av.c b/trunk/drivers/infiniband/hw/mthca/mthca_av.c index a14eed08a0fc..22fdc446f25c 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_av.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_av.c @@ -163,11 +163,6 @@ int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah) return 0; } -int mthca_ah_grh_present(struct mthca_ah *ah) -{ - return !!(ah->av->g_slid & 0x80); -} - int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, struct ib_ud_header *header) { @@ -177,7 +172,8 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, header->lrh.service_level = be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 28; header->lrh.destination_lid = ah->av->dlid; header->lrh.source_lid = cpu_to_be16(ah->av->g_slid & 0x7f); - if (mthca_ah_grh_present(ah)) { + if (ah->av->g_slid & 0x80) { + header->grh_present = 1; header->grh.traffic_class = (be32_to_cpu(ah->av->sl_tclass_flowlabel) >> 20) & 0xff; header->grh.flow_label = @@ -188,6 +184,8 @@ int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, &header->grh.source_gid); memcpy(header->grh.destination_gid.raw, ah->av->dgid, 16); + } else { + header->grh_present = 0; } return 0; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c index be1791be627b..22ac72bc20c3 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -606,7 +606,7 @@ static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm, err = -EINVAL; goto out; } - for (i = 0; i < mthca_icm_size(&iter) >> lg; ++i) { + for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i) { if (virt != -1) { pages[nent * 2] = cpu_to_be64(virt); virt += 1 << lg; @@ -727,8 +727,8 @@ int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status) * system pages needed. */ dev->fw.arbel.fw_pages = - ALIGN(dev->fw.arbel.fw_pages, PAGE_SIZE >> 12) >> - (PAGE_SHIFT - 12); + (dev->fw.arbel.fw_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> + (PAGE_SHIFT - 12); mthca_dbg(dev, "Clear int @ %llx, EQ arm @ %llx, EQ set CI @ %llx\n", (unsigned long long) dev->fw.arbel.clr_int_base, @@ -1445,7 +1445,6 @@ int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages, * pages needed. */ *aux_pages = (*aux_pages + (1 << (PAGE_SHIFT - 12)) - 1) >> (PAGE_SHIFT - 12); - *aux_pages = ALIGN(*aux_pages, PAGE_SIZE >> 12) >> (PAGE_SHIFT - 12); return 0; } diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h index a104ab041ea3..795b379260bf 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h @@ -520,7 +520,6 @@ int mthca_create_ah(struct mthca_dev *dev, int mthca_destroy_ah(struct mthca_dev *dev, struct mthca_ah *ah); int mthca_read_ah(struct mthca_dev *dev, struct mthca_ah *ah, struct ib_ud_header *header); -int mthca_ah_grh_present(struct mthca_ah *ah); int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c index 2eabb27804cd..e8a948f087c0 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c @@ -45,7 +45,6 @@ enum { MTHCA_NUM_ASYNC_EQE = 0x80, MTHCA_NUM_CMD_EQE = 0x80, - MTHCA_NUM_SPARE_EQE = 0x80, MTHCA_EQ_ENTRY_SIZE = 0x20 }; @@ -278,10 +277,11 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) { struct mthca_eqe *eqe; int disarm_cqn; - int eqes_found = 0; - int set_ci = 0; + int eqes_found = 0; while ((eqe = next_eqe_sw(eq))) { + int set_ci = 0; + /* * Make sure we read EQ entry contents after we've * checked the ownership bit. @@ -345,6 +345,12 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) be16_to_cpu(eqe->event.cmd.token), eqe->event.cmd.status, be64_to_cpu(eqe->event.cmd.out_param)); + /* + * cmd_event() may add more commands. + * The card will think the queue has overflowed if + * we don't tell it we've been processing events. + */ + set_ci = 1; break; case MTHCA_EVENT_TYPE_PORT_CHANGE: @@ -379,16 +385,8 @@ static int mthca_eq_int(struct mthca_dev *dev, struct mthca_eq *eq) set_eqe_hw(eqe); ++eq->cons_index; eqes_found = 1; - ++set_ci; - /* - * The HCA will think the queue has overflowed if we - * don't tell it we've been processing events. We - * create our EQs with MTHCA_NUM_SPARE_EQE extra - * entries, so we must update our consumer index at - * least that often. - */ - if (unlikely(set_ci >= MTHCA_NUM_SPARE_EQE)) { + if (unlikely(set_ci)) { /* * Conditional on hca_type is OK here because * this is a rare case, not the fast path. @@ -864,19 +862,19 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev) intr = (dev->mthca_flags & MTHCA_FLAG_MSI) ? 128 : dev->eq_table.inta_pin; - err = mthca_create_eq(dev, dev->limits.num_cqs + MTHCA_NUM_SPARE_EQE, + err = mthca_create_eq(dev, dev->limits.num_cqs, (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 128 : intr, &dev->eq_table.eq[MTHCA_EQ_COMP]); if (err) goto err_out_unmap; - err = mthca_create_eq(dev, MTHCA_NUM_ASYNC_EQE + MTHCA_NUM_SPARE_EQE, + err = mthca_create_eq(dev, MTHCA_NUM_ASYNC_EQE, (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 129 : intr, &dev->eq_table.eq[MTHCA_EQ_ASYNC]); if (err) goto err_out_comp; - err = mthca_create_eq(dev, MTHCA_NUM_CMD_EQE + MTHCA_NUM_SPARE_EQE, + err = mthca_create_eq(dev, MTHCA_NUM_CMD_EQE, (dev->mthca_flags & MTHCA_FLAG_MSI_X) ? 130 : intr, &dev->eq_table.eq[MTHCA_EQ_CMD]); if (err) diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c index 484a7e6b7f8c..4cc7e2846df1 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c @@ -33,7 +33,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * - * $Id: mthca_provider.c 4859 2006-01-09 21:55:10Z roland $ + * $Id: mthca_provider.c 1397 2004-12-28 05:09:00Z roland $ */ #include @@ -45,14 +45,6 @@ #include "mthca_user.h" #include "mthca_memfree.h" -static void init_query_mad(struct ib_smp *mad) -{ - mad->base_version = 1; - mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; - mad->class_version = 1; - mad->method = IB_MGMT_METHOD_GET; -} - static int mthca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) { @@ -63,7 +55,7 @@ static int mthca_query_device(struct ib_device *ibdev, u8 status; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); + in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); if (!in_mad || !out_mad) goto out; @@ -72,8 +64,12 @@ static int mthca_query_device(struct ib_device *ibdev, props->fw_ver = mdev->fw_ver; - init_query_mad(in_mad); - in_mad->attr_id = IB_SMP_ATTR_NODE_INFO; + memset(in_mad, 0, sizeof *in_mad); + in_mad->base_version = 1; + in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; + in_mad->class_version = 1; + in_mad->method = IB_MGMT_METHOD_GET; + in_mad->attr_id = IB_SMP_ATTR_NODE_INFO; err = mthca_MAD_IFC(mdev, 1, 1, 1, NULL, NULL, in_mad, out_mad, @@ -91,6 +87,7 @@ static int mthca_query_device(struct ib_device *ibdev, props->vendor_part_id = be16_to_cpup((__be16 *) (out_mad->data + 30)); props->hw_ver = be32_to_cpup((__be32 *) (out_mad->data + 32)); memcpy(&props->sys_image_guid, out_mad->data + 4, 8); + memcpy(&props->node_guid, out_mad->data + 12, 8); props->max_mr_size = ~0ull; props->page_size_cap = mdev->limits.page_size_cap; @@ -131,16 +128,20 @@ static int mthca_query_port(struct ib_device *ibdev, int err = -ENOMEM; u8 status; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); + in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); if (!in_mad || !out_mad) goto out; memset(props, 0, sizeof *props); - init_query_mad(in_mad); - in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; - in_mad->attr_mod = cpu_to_be32(port); + memset(in_mad, 0, sizeof *in_mad); + in_mad->base_version = 1; + in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; + in_mad->class_version = 1; + in_mad->method = IB_MGMT_METHOD_GET; + in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; + in_mad->attr_mod = cpu_to_be32(port); err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad, @@ -219,14 +220,18 @@ static int mthca_query_pkey(struct ib_device *ibdev, int err = -ENOMEM; u8 status; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); + in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); if (!in_mad || !out_mad) goto out; - init_query_mad(in_mad); - in_mad->attr_id = IB_SMP_ATTR_PKEY_TABLE; - in_mad->attr_mod = cpu_to_be32(index / 32); + memset(in_mad, 0, sizeof *in_mad); + in_mad->base_version = 1; + in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; + in_mad->class_version = 1; + in_mad->method = IB_MGMT_METHOD_GET; + in_mad->attr_id = IB_SMP_ATTR_PKEY_TABLE; + in_mad->attr_mod = cpu_to_be32(index / 32); err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad, @@ -254,14 +259,18 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port, int err = -ENOMEM; u8 status; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); + in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); if (!in_mad || !out_mad) goto out; - init_query_mad(in_mad); - in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; - in_mad->attr_mod = cpu_to_be32(port); + memset(in_mad, 0, sizeof *in_mad); + in_mad->base_version = 1; + in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; + in_mad->class_version = 1; + in_mad->method = IB_MGMT_METHOD_GET; + in_mad->attr_id = IB_SMP_ATTR_PORT_INFO; + in_mad->attr_mod = cpu_to_be32(port); err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad, @@ -275,9 +284,13 @@ static int mthca_query_gid(struct ib_device *ibdev, u8 port, memcpy(gid->raw, out_mad->data + 8, 8); - init_query_mad(in_mad); - in_mad->attr_id = IB_SMP_ATTR_GUID_INFO; - in_mad->attr_mod = cpu_to_be32(index / 8); + memset(in_mad, 0, sizeof *in_mad); + in_mad->base_version = 1; + in_mad->mgmt_class = IB_MGMT_CLASS_SUBN_LID_ROUTED; + in_mad->class_version = 1; + in_mad->method = IB_MGMT_METHOD_GET; + in_mad->attr_id = IB_SMP_ATTR_GUID_INFO; + in_mad->attr_mod = cpu_to_be32(index / 8); err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad, @@ -445,10 +458,8 @@ static struct ib_srq *mthca_create_srq(struct ib_pd *pd, if (pd->uobject) { context = to_mucontext(pd->uobject->context); - if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) { - err = -EFAULT; - goto err_free; - } + if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) + return ERR_PTR(-EFAULT); err = mthca_map_user_db(to_mdev(pd->device), &context->uar, context->db_tab, ucmd.db_index, @@ -524,10 +535,8 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd, if (pd->uobject) { context = to_mucontext(pd->uobject->context); - if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) { - kfree(qp); + if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) return ERR_PTR(-EFAULT); - } err = mthca_map_user_db(to_mdev(pd->device), &context->uar, context->db_tab, @@ -774,20 +783,24 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd *pd, if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) return ERR_PTR(-EINVAL); + if (num_phys_buf > 1 && + ((buffer_list[0].addr + buffer_list[0].size) & ~PAGE_MASK)) + return ERR_PTR(-EINVAL); + mask = 0; total_size = 0; for (i = 0; i < num_phys_buf; ++i) { - if (i != 0) - mask |= buffer_list[i].addr; - if (i != num_phys_buf - 1) - mask |= buffer_list[i].addr + buffer_list[i].size; + if (i != 0 && buffer_list[i].addr & ~PAGE_MASK) + return ERR_PTR(-EINVAL); + if (i != 0 && i != num_phys_buf - 1 && + (buffer_list[i].size & ~PAGE_MASK)) + return ERR_PTR(-EINVAL); total_size += buffer_list[i].size; + if (i > 0) + mask |= buffer_list[i].addr; } - if (mask & ~PAGE_MASK) - return ERR_PTR(-EINVAL); - /* Find largest page shift we can use to cover buffers */ for (shift = PAGE_SHIFT; shift < 31; ++shift) if (num_phys_buf > 1) { @@ -1057,48 +1070,11 @@ static struct class_device_attribute *mthca_class_attributes[] = { &class_device_attr_board_id }; -static int mthca_init_node_data(struct mthca_dev *dev) -{ - struct ib_smp *in_mad = NULL; - struct ib_smp *out_mad = NULL; - int err = -ENOMEM; - u8 status; - - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); - if (!in_mad || !out_mad) - goto out; - - init_query_mad(in_mad); - in_mad->attr_id = IB_SMP_ATTR_NODE_INFO; - - err = mthca_MAD_IFC(dev, 1, 1, - 1, NULL, NULL, in_mad, out_mad, - &status); - if (err) - goto out; - if (status) { - err = -EINVAL; - goto out; - } - - memcpy(&dev->ib_dev.node_guid, out_mad->data + 12, 8); - -out: - kfree(in_mad); - kfree(out_mad); - return err; -} - int mthca_register_device(struct mthca_dev *dev) { int ret; int i; - ret = mthca_init_node_data(dev); - if (ret) - return ret; - strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX); dev->ib_dev.owner = THIS_MODULE; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c index fba608ed7df2..564b6d51c394 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c @@ -1434,7 +1434,7 @@ static int build_mlx_header(struct mthca_dev *dev, struct mthca_sqp *sqp, u16 pkey; ib_ud_header_init(256, /* assume a MAD */ - mthca_ah_grh_present(to_mah(wr->wr.ud.ah)), + sqp->ud_header.grh_present, &sqp->ud_header); err = mthca_read_ah(dev, to_mah(wr->wr.ud.ah), &sqp->ud_header); diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h index e0a5412b7e68..9923a15a9996 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h @@ -45,11 +45,11 @@ #include #include #include -#include #include #include +#include #include #include @@ -123,8 +123,8 @@ struct ipoib_dev_priv { unsigned long flags; - struct mutex mcast_mutex; - struct mutex vlan_mutex; + struct semaphore mcast_mutex; + struct semaphore vlan_mutex; struct rb_root path_tree; struct list_head path_list; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 86bcdd72a107..23885801b6d2 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -52,7 +52,7 @@ MODULE_PARM_DESC(data_debug_level, #define IPOIB_OP_RECV (1ul << 31) -static DEFINE_MUTEX(pkey_mutex); +static DECLARE_MUTEX(pkey_sem); struct ipoib_ah *ipoib_create_ah(struct net_device *dev, struct ib_pd *pd, struct ib_ah_attr *attr) @@ -445,16 +445,25 @@ int ipoib_ib_dev_down(struct net_device *dev) /* Shutdown the P_Key thread if still active */ if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { - mutex_lock(&pkey_mutex); + down(&pkey_sem); set_bit(IPOIB_PKEY_STOP, &priv->flags); cancel_delayed_work(&priv->pkey_task); - mutex_unlock(&pkey_mutex); + up(&pkey_sem); flush_workqueue(ipoib_workqueue); } ipoib_mcast_stop_thread(dev, 1); + + /* + * Flush the multicast groups first so we stop any multicast joins. The + * completion thread may have already died and we may deadlock waiting + * for the completion thread to finish some multicast joins. + */ ipoib_mcast_dev_flush(dev); + /* Delete broadcast and local addresses since they will be recreated */ + ipoib_mcast_dev_down(dev); + ipoib_flush_paths(dev); return 0; @@ -599,13 +608,13 @@ void ipoib_ib_dev_flush(void *_dev) if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) ipoib_ib_dev_up(dev); - mutex_lock(&priv->vlan_mutex); + down(&priv->vlan_mutex); /* Flush any child interfaces too */ list_for_each_entry(cpriv, &priv->child_intfs, list) ipoib_ib_dev_flush(&cpriv->dev); - mutex_unlock(&priv->vlan_mutex); + up(&priv->vlan_mutex); } void ipoib_ib_dev_cleanup(struct net_device *dev) @@ -615,7 +624,9 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) ipoib_dbg(priv, "cleaning up ib_dev\n"); ipoib_mcast_stop_thread(dev, 1); - ipoib_mcast_dev_flush(dev); + + /* Delete the broadcast address and the local address */ + ipoib_mcast_dev_down(dev); ipoib_transport_dev_cleanup(dev); } @@ -651,12 +662,12 @@ void ipoib_pkey_poll(void *dev_ptr) if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) ipoib_open(dev); else { - mutex_lock(&pkey_mutex); + down(&pkey_sem); if (!test_bit(IPOIB_PKEY_STOP, &priv->flags)) queue_delayed_work(ipoib_workqueue, &priv->pkey_task, HZ); - mutex_unlock(&pkey_mutex); + up(&pkey_sem); } } @@ -670,12 +681,12 @@ int ipoib_pkey_dev_delay_open(struct net_device *dev) /* P_Key value not assigned yet - start polling */ if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { - mutex_lock(&pkey_mutex); + down(&pkey_sem); clear_bit(IPOIB_PKEY_STOP, &priv->flags); queue_delayed_work(ipoib_workqueue, &priv->pkey_task, HZ); - mutex_unlock(&pkey_mutex); + up(&pkey_sem); return 1; } diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c index fd3f5c862a5d..780009c7eaa6 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -105,7 +105,7 @@ int ipoib_open(struct net_device *dev) struct ipoib_dev_priv *cpriv; /* Bring up any child interfaces too */ - mutex_lock(&priv->vlan_mutex); + down(&priv->vlan_mutex); list_for_each_entry(cpriv, &priv->child_intfs, list) { int flags; @@ -115,7 +115,7 @@ int ipoib_open(struct net_device *dev) dev_change_flags(cpriv->dev, flags | IFF_UP); } - mutex_unlock(&priv->vlan_mutex); + up(&priv->vlan_mutex); } netif_start_queue(dev); @@ -140,7 +140,7 @@ static int ipoib_stop(struct net_device *dev) struct ipoib_dev_priv *cpriv; /* Bring down any child interfaces too */ - mutex_lock(&priv->vlan_mutex); + down(&priv->vlan_mutex); list_for_each_entry(cpriv, &priv->child_intfs, list) { int flags; @@ -150,7 +150,7 @@ static int ipoib_stop(struct net_device *dev) dev_change_flags(cpriv->dev, flags & ~IFF_UP); } - mutex_unlock(&priv->vlan_mutex); + up(&priv->vlan_mutex); } return 0; @@ -892,8 +892,8 @@ static void ipoib_setup(struct net_device *dev) spin_lock_init(&priv->lock); spin_lock_init(&priv->tx_lock); - mutex_init(&priv->mcast_mutex); - mutex_init(&priv->vlan_mutex); + init_MUTEX(&priv->mcast_mutex); + init_MUTEX(&priv->vlan_mutex); INIT_LIST_HEAD(&priv->path_list); INIT_LIST_HEAD(&priv->child_intfs); diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 98039da0caf0..ed0c2ead8bc1 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -55,7 +55,7 @@ MODULE_PARM_DESC(mcast_debug_level, "Enable multicast debug tracing if > 0"); #endif -static DEFINE_MUTEX(mcast_mutex); +static DECLARE_MUTEX(mcast_mutex); /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ struct ipoib_mcast { @@ -97,6 +97,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_neigh *neigh, *tmp; unsigned long flags; + LIST_HEAD(ah_list); + struct ipoib_ah *ah, *tah; ipoib_dbg_mcast(netdev_priv(dev), "deleting multicast group " IPOIB_GID_FMT "\n", @@ -105,14 +107,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) spin_lock_irqsave(&priv->lock, flags); list_for_each_entry_safe(neigh, tmp, &mcast->neigh_list, list) { - /* - * It's safe to call ipoib_put_ah() inside priv->lock - * here, because we know that mcast->ah will always - * hold one more reference, so ipoib_put_ah() will - * never do more than decrement the ref count. - */ if (neigh->ah) - ipoib_put_ah(neigh->ah); + list_add_tail(&neigh->ah->list, &ah_list); *to_ipoib_neigh(neigh->neighbour) = NULL; neigh->neighbour->ops->destructor = NULL; kfree(neigh); @@ -120,6 +116,9 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast) spin_unlock_irqrestore(&priv->lock, flags); + list_for_each_entry_safe(ah, tah, &ah_list, list) + ipoib_put_ah(ah); + if (mcast->ah) ipoib_put_ah(mcast->ah); @@ -385,10 +384,10 @@ static void ipoib_mcast_join_complete(int status, if (!status && !ipoib_mcast_join_finish(mcast, mcmember)) { mcast->backoff = 1; - mutex_lock(&mcast_mutex); + down(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) queue_work(ipoib_workqueue, &priv->mcast_task); - mutex_unlock(&mcast_mutex); + up(&mcast_mutex); complete(&mcast->done); return; } @@ -418,7 +417,7 @@ static void ipoib_mcast_join_complete(int status, mcast->query = NULL; - mutex_lock(&mcast_mutex); + down(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) { if (status == -ETIMEDOUT) queue_work(ipoib_workqueue, &priv->mcast_task); @@ -427,7 +426,7 @@ static void ipoib_mcast_join_complete(int status, mcast->backoff * HZ); } else complete(&mcast->done); - mutex_unlock(&mcast_mutex); + up(&mcast_mutex); return; } @@ -482,12 +481,12 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast, if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS) mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS; - mutex_lock(&mcast_mutex); + down(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) queue_delayed_work(ipoib_workqueue, &priv->mcast_task, mcast->backoff * HZ); - mutex_unlock(&mcast_mutex); + up(&mcast_mutex); } else mcast->query_id = ret; } @@ -520,11 +519,11 @@ void ipoib_mcast_join_task(void *dev_ptr) priv->broadcast = ipoib_mcast_alloc(dev, 1); if (!priv->broadcast) { ipoib_warn(priv, "failed to allocate broadcast group\n"); - mutex_lock(&mcast_mutex); + down(&mcast_mutex); if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) queue_delayed_work(ipoib_workqueue, &priv->mcast_task, HZ); - mutex_unlock(&mcast_mutex); + up(&mcast_mutex); return; } @@ -580,10 +579,10 @@ int ipoib_mcast_start_thread(struct net_device *dev) ipoib_dbg_mcast(priv, "starting multicast thread\n"); - mutex_lock(&mcast_mutex); + down(&mcast_mutex); if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags)) queue_work(ipoib_workqueue, &priv->mcast_task); - mutex_unlock(&mcast_mutex); + up(&mcast_mutex); return 0; } @@ -595,10 +594,10 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush) ipoib_dbg_mcast(priv, "stopping multicast thread\n"); - mutex_lock(&mcast_mutex); + down(&mcast_mutex); clear_bit(IPOIB_MCAST_RUN, &priv->flags); cancel_delayed_work(&priv->mcast_task); - mutex_unlock(&mcast_mutex); + up(&mcast_mutex); if (flush) flush_workqueue(ipoib_workqueue); @@ -742,23 +741,48 @@ void ipoib_mcast_dev_flush(struct net_device *dev) { struct ipoib_dev_priv *priv = netdev_priv(dev); LIST_HEAD(remove_list); - struct ipoib_mcast *mcast, *tmcast; + struct ipoib_mcast *mcast, *tmcast, *nmcast; unsigned long flags; ipoib_dbg_mcast(priv, "flushing multicast list\n"); spin_lock_irqsave(&priv->lock, flags); - list_for_each_entry_safe(mcast, tmcast, &priv->multicast_list, list) { - list_del(&mcast->list); - rb_erase(&mcast->rb_node, &priv->multicast_tree); - list_add_tail(&mcast->list, &remove_list); + nmcast = ipoib_mcast_alloc(dev, 0); + if (nmcast) { + nmcast->flags = + mcast->flags & (1 << IPOIB_MCAST_FLAG_SENDONLY); + + nmcast->mcmember.mgid = mcast->mcmember.mgid; + + /* Add the new group in before the to-be-destroyed group */ + list_add_tail(&nmcast->list, &mcast->list); + list_del_init(&mcast->list); + + rb_replace_node(&mcast->rb_node, &nmcast->rb_node, + &priv->multicast_tree); + + list_add_tail(&mcast->list, &remove_list); + } else { + ipoib_warn(priv, "could not reallocate multicast group " + IPOIB_GID_FMT "\n", + IPOIB_GID_ARG(mcast->mcmember.mgid)); + } } if (priv->broadcast) { - rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree); - list_add_tail(&priv->broadcast->list, &remove_list); - priv->broadcast = NULL; + nmcast = ipoib_mcast_alloc(dev, 0); + if (nmcast) { + nmcast->mcmember.mgid = priv->broadcast->mcmember.mgid; + + rb_replace_node(&priv->broadcast->rb_node, + &nmcast->rb_node, + &priv->multicast_tree); + + list_add_tail(&priv->broadcast->list, &remove_list); + } + + priv->broadcast = nmcast; } spin_unlock_irqrestore(&priv->lock, flags); @@ -769,6 +793,24 @@ void ipoib_mcast_dev_flush(struct net_device *dev) } } +void ipoib_mcast_dev_down(struct net_device *dev) +{ + struct ipoib_dev_priv *priv = netdev_priv(dev); + unsigned long flags; + + /* Delete broadcast since it will be recreated */ + if (priv->broadcast) { + ipoib_dbg_mcast(priv, "deleting broadcast group\n"); + + spin_lock_irqsave(&priv->lock, flags); + rb_erase(&priv->broadcast->rb_node, &priv->multicast_tree); + spin_unlock_irqrestore(&priv->lock, flags); + ipoib_mcast_leave(dev, priv->broadcast); + ipoib_mcast_free(priv->broadcast); + priv->broadcast = NULL; + } +} + void ipoib_mcast_restart_task(void *dev_ptr) { struct net_device *dev = dev_ptr; @@ -782,8 +824,7 @@ void ipoib_mcast_restart_task(void *dev_ptr) ipoib_mcast_stop_thread(dev, 0); - spin_lock_irqsave(&dev->xmit_lock, flags); - spin_lock(&priv->lock); + spin_lock_irqsave(&priv->lock, flags); /* * Unfortunately, the networking core only gives us a list of all of @@ -855,9 +896,7 @@ void ipoib_mcast_restart_task(void *dev_ptr) list_add_tail(&mcast->list, &remove_list); } } - - spin_unlock(&priv->lock); - spin_unlock_irqrestore(&dev->xmit_lock, flags); + spin_unlock_irqrestore(&priv->lock, flags); /* We have to cancel outside of the spinlock */ list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index faaf10e5fc7b..e829e10400e3 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -65,9 +65,9 @@ int ipoib_mcast_attach(struct net_device *dev, u16 mlid, union ib_gid *mgid) } /* attach QP to multicast group */ - mutex_lock(&priv->mcast_mutex); + down(&priv->mcast_mutex); ret = ib_attach_mcast(priv->qp, mgid, mlid); - mutex_unlock(&priv->mcast_mutex); + up(&priv->mcast_mutex); if (ret) ipoib_warn(priv, "failed to attach to multicast group, ret = %d\n", ret); @@ -81,9 +81,9 @@ int ipoib_mcast_detach(struct net_device *dev, u16 mlid, union ib_gid *mgid) struct ipoib_dev_priv *priv = netdev_priv(dev); int ret; - mutex_lock(&priv->mcast_mutex); + down(&priv->mcast_mutex); ret = ib_detach_mcast(priv->qp, mgid, mlid); - mutex_unlock(&priv->mcast_mutex); + up(&priv->mcast_mutex); if (ret) ipoib_warn(priv, "ib_detach_mcast failed (result = %d)\n", ret); diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 4ca175553f9f..d280b341a37f 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -63,7 +63,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) ppriv = netdev_priv(pdev); - mutex_lock(&ppriv->vlan_mutex); + down(&ppriv->vlan_mutex); /* * First ensure this isn't a duplicate. We check the parent device and @@ -124,7 +124,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) list_add_tail(&priv->list, &ppriv->child_intfs); - mutex_unlock(&ppriv->vlan_mutex); + up(&ppriv->vlan_mutex); return 0; @@ -139,7 +139,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) free_netdev(priv->dev); err: - mutex_unlock(&ppriv->vlan_mutex); + up(&ppriv->vlan_mutex); return result; } @@ -153,7 +153,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) ppriv = netdev_priv(pdev); - mutex_lock(&ppriv->vlan_mutex); + down(&ppriv->vlan_mutex); list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) { if (priv->pkey == pkey) { unregister_netdev(priv->dev); @@ -167,7 +167,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) break; } } - mutex_unlock(&ppriv->vlan_mutex); + up(&ppriv->vlan_mutex); return ret; } diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.c b/trunk/drivers/infiniband/ulp/srp/ib_srp.c index 31207e664148..dd488d3cffa9 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.c +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.c @@ -1516,7 +1516,8 @@ static ssize_t show_port(struct class_device *class_dev, char *buf) static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); -static struct srp_host *srp_add_port(struct ib_device *device, u8 port) +static struct srp_host *srp_add_port(struct ib_device *device, + __be64 node_guid, u8 port) { struct srp_host *host; @@ -1531,7 +1532,7 @@ static struct srp_host *srp_add_port(struct ib_device *device, u8 port) host->port = port; host->initiator_port_id[7] = port; - memcpy(host->initiator_port_id + 8, &device->node_guid, 8); + memcpy(host->initiator_port_id + 8, &node_guid, 8); host->pd = ib_alloc_pd(device); if (IS_ERR(host->pd)) @@ -1579,11 +1580,22 @@ static void srp_add_one(struct ib_device *device) { struct list_head *dev_list; struct srp_host *host; + struct ib_device_attr *dev_attr; int s, e, p; + dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL); + if (!dev_attr) + return; + + if (ib_query_device(device, dev_attr)) { + printk(KERN_WARNING PFX "Couldn't query node GUID for %s.\n", + device->name); + goto out; + } + dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL); if (!dev_list) - return; + goto out; INIT_LIST_HEAD(dev_list); @@ -1596,12 +1608,15 @@ static void srp_add_one(struct ib_device *device) } for (p = s; p <= e; ++p) { - host = srp_add_port(device, p); + host = srp_add_port(device, dev_attr->node_guid, p); if (host) list_add_tail(&host->list, dev_list); } ib_set_client_data(device, &srp_client, dev_list); + +out: + kfree(dev_attr); } static void srp_remove_one(struct ib_device *device) diff --git a/trunk/drivers/input/mouse/alps.c b/trunk/drivers/input/mouse/alps.c index 2141501e9f2e..24474335dfd1 100644 --- a/trunk/drivers/input/mouse/alps.c +++ b/trunk/drivers/input/mouse/alps.c @@ -348,40 +348,6 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable) return 0; } -/* - * alps_poll() - poll the touchpad for current motion packet. - * Used in resync. - */ -static int alps_poll(struct psmouse *psmouse) -{ - struct alps_data *priv = psmouse->private; - unsigned char buf[6]; - int poll_failed; - - if (priv->i->flags & ALPS_PASS) - alps_passthrough_mode(psmouse, 1); - - poll_failed = ps2_command(&psmouse->ps2dev, buf, - PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0; - - if (priv->i->flags & ALPS_PASS) - alps_passthrough_mode(psmouse, 0); - - if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0) - return -1; - - if ((psmouse->badbyte & 0xc8) == 0x08) { -/* - * Poll the track stick ... - */ - if (ps2_command(&psmouse->ps2dev, buf, PSMOUSE_CMD_POLL | (3 << 8))) - return -1; - } - - memcpy(psmouse->packet, buf, sizeof(buf)); - return 0; -} - static int alps_reconnect(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; @@ -485,14 +451,10 @@ int alps_init(struct psmouse *psmouse) input_register_device(priv->dev2); psmouse->protocol_handler = alps_process_byte; - psmouse->poll = alps_poll; psmouse->disconnect = alps_disconnect; psmouse->reconnect = alps_reconnect; psmouse->pktsize = 6; - /* We are having trouble resyncing ALPS touchpads so disable it for now */ - psmouse->resync_time = 0; - return 0; init_fail: diff --git a/trunk/drivers/input/mouse/logips2pp.c b/trunk/drivers/input/mouse/logips2pp.c index c88520d3d13c..025a71de5404 100644 --- a/trunk/drivers/input/mouse/logips2pp.c +++ b/trunk/drivers/input/mouse/logips2pp.c @@ -117,7 +117,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha if (psmouse_sliced_command(psmouse, command)) return -1; - if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL | 0x0300)) + if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_POLL)) return -1; return 0; diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index 7665fd9ce559..4d5ecc04c5b6 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -54,14 +54,10 @@ static unsigned int psmouse_smartscroll = 1; module_param_named(smartscroll, psmouse_smartscroll, bool, 0644); MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); -static unsigned int psmouse_resetafter = 5; +static unsigned int psmouse_resetafter; module_param_named(resetafter, psmouse_resetafter, uint, 0644); MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); -static unsigned int psmouse_resync_time = 5; -module_param_named(resync_time, psmouse_resync_time, uint, 0644); -MODULE_PARM_DESC(resync_time, "How long can mouse stay idle before forcing resync (in seconds, 0 = never)."); - PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO, NULL, psmouse_attr_show_protocol, psmouse_attr_set_protocol); @@ -74,16 +70,12 @@ PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO, PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO, (void *) offsetof(struct psmouse, resetafter), psmouse_show_int_attr, psmouse_set_int_attr); -PSMOUSE_DEFINE_ATTR(resync_time, S_IWUSR | S_IRUGO, - (void *) offsetof(struct psmouse, resync_time), - psmouse_show_int_attr, psmouse_set_int_attr); static struct attribute *psmouse_attributes[] = { &psmouse_attr_protocol.dattr.attr, &psmouse_attr_rate.dattr.attr, &psmouse_attr_resolution.dattr.attr, &psmouse_attr_resetafter.dattr.attr, - &psmouse_attr_resync_time.dattr.attr, NULL }; @@ -106,8 +98,6 @@ __obsolete_setup("psmouse_rate="); */ static DECLARE_MUTEX(psmouse_sem); -static struct workqueue_struct *kpsmoused_wq; - struct psmouse_protocol { enum psmouse_type type; char *name; @@ -188,79 +178,15 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_reg } /* - * __psmouse_set_state() sets new psmouse state and resets all flags. - */ - -static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) -{ - psmouse->state = new_state; - psmouse->pktcnt = psmouse->out_of_sync = 0; - psmouse->ps2dev.flags = 0; - psmouse->last = jiffies; -} - - -/* - * psmouse_set_state() sets new psmouse state and resets all flags and - * counters while holding serio lock so fighting with interrupt handler - * is not a concern. - */ - -static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) -{ - serio_pause_rx(psmouse->ps2dev.serio); - __psmouse_set_state(psmouse, new_state); - serio_continue_rx(psmouse->ps2dev.serio); -} - -/* - * psmouse_handle_byte() processes one byte of the input data stream - * by calling corresponding protocol handler. - */ - -static int psmouse_handle_byte(struct psmouse *psmouse, struct pt_regs *regs) -{ - psmouse_ret_t rc = psmouse->protocol_handler(psmouse, regs); - - switch (rc) { - case PSMOUSE_BAD_DATA: - if (psmouse->state == PSMOUSE_ACTIVATED) { - printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", - psmouse->name, psmouse->phys, psmouse->pktcnt); - if (++psmouse->out_of_sync == psmouse->resetafter) { - __psmouse_set_state(psmouse, PSMOUSE_IGNORE); - printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); - serio_reconnect(psmouse->ps2dev.serio); - return -1; - } - } - psmouse->pktcnt = 0; - break; - - case PSMOUSE_FULL_PACKET: - psmouse->pktcnt = 0; - if (psmouse->out_of_sync) { - psmouse->out_of_sync = 0; - printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", - psmouse->name, psmouse->phys); - } - break; - - case PSMOUSE_GOOD_DATA: - break; - } - return 0; -} - -/* - * psmouse_interrupt() handles incoming characters, either passing them - * for normal processing or gathering them as command response. + * psmouse_interrupt() handles incoming characters, either gathering them into + * packets or passing them to the command routine as command output. */ static irqreturn_t psmouse_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs) { struct psmouse *psmouse = serio_get_drvdata(serio); + psmouse_ret_t rc; if (psmouse->state == PSMOUSE_IGNORE) goto out; @@ -282,58 +208,67 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, if (ps2_handle_response(&psmouse->ps2dev, data)) goto out; - if (psmouse->state <= PSMOUSE_RESYNCING) + if (psmouse->state == PSMOUSE_INITIALIZING) goto out; if (psmouse->state == PSMOUSE_ACTIVATED && psmouse->pktcnt && time_after(jiffies, psmouse->last + HZ/2)) { - printk(KERN_INFO "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n", + printk(KERN_WARNING "psmouse.c: %s at %s lost synchronization, throwing %d bytes away.\n", psmouse->name, psmouse->phys, psmouse->pktcnt); - psmouse->badbyte = psmouse->packet[0]; - __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); - queue_work(kpsmoused_wq, &psmouse->resync_work); - goto out; + psmouse->pktcnt = 0; } + psmouse->last = jiffies; psmouse->packet[psmouse->pktcnt++] = data; -/* - * Check if this is a new device announcement (0xAA 0x00) - */ - if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) { + + if (psmouse->packet[0] == PSMOUSE_RET_BAT) { if (psmouse->pktcnt == 1) goto out; - if (psmouse->packet[1] == PSMOUSE_RET_ID) { - __psmouse_set_state(psmouse, PSMOUSE_IGNORE); - serio_reconnect(serio); - goto out; + if (psmouse->pktcnt == 2) { + if (psmouse->packet[1] == PSMOUSE_RET_ID) { + psmouse->state = PSMOUSE_IGNORE; + serio_reconnect(serio); + goto out; + } + if (psmouse->type == PSMOUSE_SYNAPTICS) { + /* neither 0xAA nor 0x00 are valid first bytes + * for a packet in absolute mode + */ + psmouse->pktcnt = 0; + goto out; + } } -/* - * Not a new device, try processing first byte normally - */ - psmouse->pktcnt = 1; - if (psmouse_handle_byte(psmouse, regs)) - goto out; - - psmouse->packet[psmouse->pktcnt++] = data; } -/* - * See if we need to force resync because mouse was idle for too long - */ - if (psmouse->state == PSMOUSE_ACTIVATED && - psmouse->pktcnt == 1 && psmouse->resync_time && - time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) { - psmouse->badbyte = psmouse->packet[0]; - __psmouse_set_state(psmouse, PSMOUSE_RESYNCING); - queue_work(kpsmoused_wq, &psmouse->resync_work); - goto out; - } + rc = psmouse->protocol_handler(psmouse, regs); - psmouse->last = jiffies; - psmouse_handle_byte(psmouse, regs); + switch (rc) { + case PSMOUSE_BAD_DATA: + printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n", + psmouse->name, psmouse->phys, psmouse->pktcnt); + psmouse->pktcnt = 0; - out: + if (++psmouse->out_of_sync == psmouse->resetafter) { + psmouse->state = PSMOUSE_IGNORE; + printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n"); + serio_reconnect(psmouse->ps2dev.serio); + } + break; + + case PSMOUSE_FULL_PACKET: + psmouse->pktcnt = 0; + if (psmouse->out_of_sync) { + psmouse->out_of_sync = 0; + printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n", + psmouse->name, psmouse->phys); + } + break; + + case PSMOUSE_GOOD_DATA: + break; + } +out: return IRQ_HANDLED; } @@ -816,6 +751,21 @@ static void psmouse_initialize(struct psmouse *psmouse) } } +/* + * psmouse_set_state() sets new psmouse state and resets all flags and + * counters while holding serio lock so fighting with interrupt handler + * is not a concern. + */ + +static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state) +{ + serio_pause_rx(psmouse->ps2dev.serio); + psmouse->state = new_state; + psmouse->pktcnt = psmouse->out_of_sync = 0; + psmouse->ps2dev.flags = 0; + serio_continue_rx(psmouse->ps2dev.serio); +} + /* * psmouse_activate() enables the mouse so that we get motion reports from it. */ @@ -844,111 +794,6 @@ static void psmouse_deactivate(struct psmouse *psmouse) psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); } -/* - * psmouse_poll() - default poll hanlder. Everyone except for ALPS uses it. - */ - -static int psmouse_poll(struct psmouse *psmouse) -{ - return ps2_command(&psmouse->ps2dev, psmouse->packet, - PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)); -} - - -/* - * psmouse_resync() attempts to re-validate current protocol. - */ - -static void psmouse_resync(void *p) -{ - struct psmouse *psmouse = p, *parent = NULL; - struct serio *serio = psmouse->ps2dev.serio; - psmouse_ret_t rc = PSMOUSE_GOOD_DATA; - int failed = 0, enabled = 0; - int i; - - down(&psmouse_sem); - - if (psmouse->state != PSMOUSE_RESYNCING) - goto out; - - if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { - parent = serio_get_drvdata(serio->parent); - psmouse_deactivate(parent); - } - -/* - * Some mice don't ACK commands sent while they are in the middle of - * transmitting motion packet. To avoid delay we use ps2_sendbyte() - * instead of ps2_command() which would wait for 200ms for an ACK - * that may never come. - * As an additional quirk ALPS touchpads may not only forget to ACK - * disable command but will stop reporting taps, so if we see that - * mouse at least once ACKs disable we will do full reconnect if ACK - * is missing. - */ - psmouse->num_resyncs++; - - if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) { - if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command) - failed = 1; - } else - psmouse->acks_disable_command = 1; - -/* - * Poll the mouse. If it was reset the packet will be shorter than - * psmouse->pktsize and ps2_command will fail. We do not expect and - * do not handle scenario when mouse "upgrades" its protocol while - * disconnected since it would require additional delay. If we ever - * see a mouse that does it we'll adjust the code. - */ - if (!failed) { - if (psmouse->poll(psmouse)) - failed = 1; - else { - psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); - for (i = 0; i < psmouse->pktsize; i++) { - psmouse->pktcnt++; - rc = psmouse->protocol_handler(psmouse, NULL); - if (rc != PSMOUSE_GOOD_DATA) - break; - } - if (rc != PSMOUSE_FULL_PACKET) - failed = 1; - psmouse_set_state(psmouse, PSMOUSE_RESYNCING); - } - } -/* - * Now try to enable mouse. We try to do that even if poll failed and also - * repeat our attempts 5 times, otherwise we may be left out with disabled - * mouse. - */ - for (i = 0; i < 5; i++) { - if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) { - enabled = 1; - break; - } - msleep(200); - } - - if (!enabled) { - printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n", - psmouse->ps2dev.serio->phys); - failed = 1; - } - - if (failed) { - psmouse_set_state(psmouse, PSMOUSE_IGNORE); - printk(KERN_INFO "psmouse.c: resync failed, issuing reconnect request\n"); - serio_reconnect(serio); - } else - psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); - - if (parent) - psmouse_activate(parent); - out: - up(&psmouse_sem); -} /* * psmouse_cleanup() resets the mouse into power-on state. @@ -977,11 +822,6 @@ static void psmouse_disconnect(struct serio *serio) psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); - /* make sure we don't have a resync in progress */ - up(&psmouse_sem); - flush_workqueue(kpsmoused_wq); - down(&psmouse_sem); - if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { parent = serio_get_drvdata(serio->parent); psmouse_deactivate(parent); @@ -1019,7 +859,6 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto psmouse->set_rate = psmouse_set_rate; psmouse->set_resolution = psmouse_set_resolution; - psmouse->poll = psmouse_poll; psmouse->protocol_handler = psmouse_process_byte; psmouse->pktsize = 3; @@ -1035,23 +874,6 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto else psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); - /* - * If mouse's packet size is 3 there is no point in polling the - * device in hopes to detect protocol reset - we won't get less - * than 3 bytes response anyhow. - */ - if (psmouse->pktsize == 3) - psmouse->resync_time = 0; - - /* - * Some smart KVMs fake response to POLL command returning just - * 3 bytes and messing up our resync logic, so if initial poll - * fails we won't try polling the device anymore. Hopefully - * such KVM will maintain initially selected protocol. - */ - if (psmouse->resync_time && psmouse->poll(psmouse)) - psmouse->resync_time = 0; - sprintf(psmouse->devname, "%s %s %s", psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); @@ -1092,7 +914,6 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) goto out; ps2_init(&psmouse->ps2dev, serio); - INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse); psmouse->dev = input_dev; sprintf(psmouse->phys, "%s/input0", serio->phys); @@ -1113,7 +934,6 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) psmouse->rate = psmouse_rate; psmouse->resolution = psmouse_resolution; psmouse->resetafter = psmouse_resetafter; - psmouse->resync_time = parent ? 0 : psmouse_resync_time; psmouse->smartscroll = psmouse_smartscroll; psmouse_switch_protocol(psmouse, NULL); @@ -1458,21 +1278,13 @@ static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) static int __init psmouse_init(void) { - kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); - if (!kpsmoused_wq) { - printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n"); - return -ENOMEM; - } - serio_register_driver(&psmouse_drv); - return 0; } static void __exit psmouse_exit(void) { serio_unregister_driver(&psmouse_drv); - destroy_workqueue(kpsmoused_wq); } module_init(psmouse_init); diff --git a/trunk/drivers/input/mouse/psmouse.h b/trunk/drivers/input/mouse/psmouse.h index 4d9107fba6a1..7c4192bd1279 100644 --- a/trunk/drivers/input/mouse/psmouse.h +++ b/trunk/drivers/input/mouse/psmouse.h @@ -7,7 +7,7 @@ #define PSMOUSE_CMD_GETINFO 0x03e9 #define PSMOUSE_CMD_SETSTREAM 0x00ea #define PSMOUSE_CMD_SETPOLL 0x00f0 -#define PSMOUSE_CMD_POLL 0x00eb /* caller sets number of bytes to receive */ +#define PSMOUSE_CMD_POLL 0x03eb #define PSMOUSE_CMD_GETID 0x02f2 #define PSMOUSE_CMD_SETRATE 0x10f3 #define PSMOUSE_CMD_ENABLE 0x00f4 @@ -23,7 +23,6 @@ enum psmouse_state { PSMOUSE_IGNORE, PSMOUSE_INITIALIZING, - PSMOUSE_RESYNCING, PSMOUSE_CMD_MODE, PSMOUSE_ACTIVATED, }; @@ -39,19 +38,15 @@ struct psmouse { void *private; struct input_dev *dev; struct ps2dev ps2dev; - struct work_struct resync_work; char *vendor; char *name; unsigned char packet[8]; - unsigned char badbyte; unsigned char pktcnt; unsigned char pktsize; unsigned char type; - unsigned char acks_disable_command; unsigned int model; unsigned long last; unsigned long out_of_sync; - unsigned long num_resyncs; enum psmouse_state state; char devname[64]; char phys[32]; @@ -59,7 +54,6 @@ struct psmouse { unsigned int rate; unsigned int resolution; unsigned int resetafter; - unsigned int resync_time; unsigned int smartscroll; /* Logitech only */ psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs); @@ -68,7 +62,6 @@ struct psmouse { int (*reconnect)(struct psmouse *psmouse); void (*disconnect)(struct psmouse *psmouse); - int (*poll)(struct psmouse *psmouse); void (*pt_activate)(struct psmouse *psmouse); void (*pt_deactivate)(struct psmouse *psmouse); diff --git a/trunk/drivers/input/mouse/synaptics.c b/trunk/drivers/input/mouse/synaptics.c index 2051bec2c394..97cdfd6acaca 100644 --- a/trunk/drivers/input/mouse/synaptics.c +++ b/trunk/drivers/input/mouse/synaptics.c @@ -652,8 +652,6 @@ int synaptics_init(struct psmouse *psmouse) psmouse->disconnect = synaptics_disconnect; psmouse->reconnect = synaptics_reconnect; psmouse->pktsize = 6; - /* Synaptics can usually stay in sync without extra help */ - psmouse->resync_time = 0; if (SYN_CAP_PASS_THROUGH(priv->capabilities)) synaptics_pt_create(psmouse); diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h index a4c6f3522723..2d2f9fb3aded 100644 --- a/trunk/drivers/input/serio/i8042-x86ia64io.h +++ b/trunk/drivers/input/serio/i8042-x86ia64io.h @@ -173,13 +173,6 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), }, }, - { - .ident = "Sony Vaio FS-115b", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), - }, - }, { } }; diff --git a/trunk/drivers/macintosh/macio-adb.c b/trunk/drivers/macintosh/macio-adb.c index 314fc0830d90..cf6a6f2248ac 100644 --- a/trunk/drivers/macintosh/macio-adb.c +++ b/trunk/drivers/macintosh/macio-adb.c @@ -17,7 +17,6 @@ #include #include #include -#include struct preg { unsigned char r; @@ -89,26 +88,24 @@ int macio_probe(void) int macio_init(void) { struct device_node *adbs; - struct resource r; adbs = find_compatible_devices("adb", "chrp,adb0"); if (adbs == 0) return -ENXIO; #if 0 - { int i = 0; + { int i; printk("macio_adb_init: node = %p, addrs =", adbs->node); - while(!of_address_to_resource(adbs, i, &r)) - printk(" %x(%x)", r.start, r.end - r.start); + for (i = 0; i < adbs->n_addrs; ++i) + printk(" %x(%x)", adbs->addrs[i].address, adbs->addrs[i].size); printk(", intrs ="); for (i = 0; i < adbs->n_intrs; ++i) printk(" %x", adbs->intrs[i].line); printk("\n"); } #endif - if (of_address_to_resource(adbs, 0, &r)) - return -ENXIO; - adb = ioremap(r.start, sizeof(struct adb_regs)); + + adb = ioremap(adbs->addrs->address, sizeof(struct adb_regs)); out_8(&adb->ctrl.r, 0); out_8(&adb->intr.r, 0); diff --git a/trunk/drivers/usb/input/Kconfig b/trunk/drivers/usb/input/Kconfig index 5246b35301de..509dd0a04c54 100644 --- a/trunk/drivers/usb/input/Kconfig +++ b/trunk/drivers/usb/input/Kconfig @@ -37,16 +37,6 @@ config USB_HIDINPUT If unsure, say Y. -config USB_HIDINPUT_POWERBOOK - bool "Enable support for iBook/PowerBook special keys" - default n - depends on USB_HIDINPUT - help - Say Y here if you want support for the special keys (Fn, Numlock) on - Apple iBooks and PowerBooks. - - If unsure, say N. - config HID_FF bool "Force feedback support (EXPERIMENTAL)" depends on USB_HIDINPUT && EXPERIMENTAL diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index a91e72c41415..5f52979af1c7 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -1450,9 +1450,6 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_APPLE 0x05ac #define USB_DEVICE_ID_APPLE_POWERMOUSE 0x0304 -#define USB_VENDOR_ID_CHERRY 0x046a -#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 - /* * Alphabetically sorted blacklist by quirk type. */ @@ -1583,16 +1580,6 @@ static const struct hid_blacklist { { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD }, { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD }, - { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, - - { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN }, - { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN }, - { 0, 0 } }; @@ -1639,20 +1626,6 @@ static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); } -/* - * Cherry Cymotion keyboard have an invalid HID report descriptor, - * that needs fixing before we can parse it. - */ - -static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize) -{ - if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { - info("Fixing up Cherry Cymotion report descriptor"); - rdesc[11] = rdesc[16] = 0xff; - rdesc[12] = rdesc[17] = 0x03; - } -} - static struct hid_device *usb_hid_configure(struct usb_interface *intf) { struct usb_host_interface *interface = intf->cur_altsetting; @@ -1700,9 +1673,6 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) return NULL; } - if ((quirks & HID_QUIRK_CYMOTION)) - hid_fixup_cymotion_descriptor(rdesc, rsize); - #ifdef DEBUG_DATA printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n); for (n = 0; n < rsize; n++) diff --git a/trunk/drivers/usb/input/hid-input.c b/trunk/drivers/usb/input/hid-input.c index cb0d80f49252..192a03b28971 100644 --- a/trunk/drivers/usb/input/hid-input.c +++ b/trunk/drivers/usb/input/hid-input.c @@ -73,160 +73,6 @@ static const struct { #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) #define map_ff_effect(c) do { set_bit(c, input->ffbit); } while (0) -#ifdef CONFIG_USB_HIDINPUT_POWERBOOK - -struct hidinput_key_translation { - u16 from; - u16 to; - u8 flags; -}; - -#define POWERBOOK_FLAG_FKEY 0x01 - -static struct hidinput_key_translation powerbook_fn_keys[] = { - { KEY_BACKSPACE, KEY_DELETE }, - { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY }, - { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY }, - { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY }, - { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY }, - { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY }, - { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY }, - { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY }, - { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY }, - { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY }, - { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY }, - { KEY_UP, KEY_PAGEUP }, - { KEY_DOWN, KEY_PAGEDOWN }, - { KEY_LEFT, KEY_HOME }, - { KEY_RIGHT, KEY_END }, - { } -}; - -static struct hidinput_key_translation powerbook_numlock_keys[] = { - { KEY_J, KEY_KP1 }, - { KEY_K, KEY_KP2 }, - { KEY_L, KEY_KP3 }, - { KEY_U, KEY_KP4 }, - { KEY_I, KEY_KP5 }, - { KEY_O, KEY_KP6 }, - { KEY_7, KEY_KP7 }, - { KEY_8, KEY_KP8 }, - { KEY_9, KEY_KP9 }, - { KEY_M, KEY_KP0 }, - { KEY_DOT, KEY_KPDOT }, - { KEY_SLASH, KEY_KPPLUS }, - { KEY_SEMICOLON, KEY_KPMINUS }, - { KEY_P, KEY_KPASTERISK }, - { KEY_MINUS, KEY_KPEQUAL }, - { KEY_0, KEY_KPSLASH }, - { KEY_F6, KEY_NUMLOCK }, - { KEY_KPENTER, KEY_KPENTER }, - { KEY_BACKSPACE, KEY_BACKSPACE }, - { } -}; - -static int usbhid_pb_fnmode = 1; -module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644); -MODULE_PARM_DESC(pb_fnmode, - "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); - -static struct hidinput_key_translation *find_translation(struct hidinput_key_translation *table, u16 from) -{ - struct hidinput_key_translation *trans; - - /* Look for the translation */ - for (trans = table; trans->from; trans++) - if (trans->from == from) - return trans; - - return NULL; -} - -static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, - struct hid_usage *usage, __s32 value) -{ - struct hidinput_key_translation *trans; - - if (usage->code == KEY_FN) { - if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON; - else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON; - - input_event(input, usage->type, usage->code, value); - - return 1; - } - - if (usbhid_pb_fnmode) { - int do_translate; - - trans = find_translation(powerbook_fn_keys, usage->code); - if (trans) { - if (test_bit(usage->code, hid->pb_pressed_fn)) - do_translate = 1; - else if (trans->flags & POWERBOOK_FLAG_FKEY) - do_translate = - (usbhid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || - (usbhid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); - else - do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); - - if (do_translate) { - if (value) - set_bit(usage->code, hid->pb_pressed_fn); - else - clear_bit(usage->code, hid->pb_pressed_fn); - - input_event(input, usage->type, trans->to, value); - - return 1; - } - } - - if (test_bit(usage->code, hid->pb_pressed_numlock) || - test_bit(LED_NUML, input->led)) { - trans = find_translation(powerbook_numlock_keys, usage->code); - - if (trans) { - if (value) - set_bit(usage->code, hid->pb_pressed_numlock); - else - clear_bit(usage->code, hid->pb_pressed_numlock); - - input_event(input, usage->type, trans->to, value); - } - - return 1; - } - } - - return 0; -} - -static void hidinput_pb_setup(struct input_dev *input) -{ - struct hidinput_key_translation *trans; - - set_bit(KEY_NUMLOCK, input->keybit); - - /* Enable all needed keys */ - for (trans = powerbook_fn_keys; trans->from; trans++) - set_bit(trans->to, input->keybit); - - for (trans = powerbook_numlock_keys; trans->from; trans++) - set_bit(trans->to, input->keybit); -} -#else -static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, - struct hid_usage *usage, __s32 value) -{ - return 0; -} - -static inline void hidinput_pb_setup(struct input_dev *input) -{ -} -#endif - static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, struct hid_usage *usage) { @@ -289,11 +135,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case HID_UP_SIMULATION: switch (usage->hid & 0xffff) { - case 0xba: map_abs(ABS_RUDDER); break; + case 0xba: map_abs(ABS_RUDDER); break; case 0xbb: map_abs(ABS_THROTTLE); break; - case 0xc4: map_abs(ABS_GAS); break; - case 0xc5: map_abs(ABS_BRAKE); break; - case 0xc8: map_abs(ABS_WHEEL); break; default: goto ignore; } break; @@ -446,19 +289,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x226: map_key_clear(KEY_STOP); break; case 0x227: map_key_clear(KEY_REFRESH); break; case 0x22a: map_key_clear(KEY_BOOKMARKS); break; - case 0x233: map_key_clear(KEY_SCROLLUP); break; - case 0x234: map_key_clear(KEY_SCROLLDOWN); break; case 0x238: map_rel(REL_HWHEEL); break; case 0x279: map_key_clear(KEY_REDO); break; case 0x289: map_key_clear(KEY_REPLY); break; case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; case 0x28c: map_key_clear(KEY_SEND); break; - - /* Reported on a Cherry Cymotion keyboard */ - case 0x301: map_key_clear(KEY_PROG1); break; - case 0x302: map_key_clear(KEY_PROG2); break; - case 0x303: map_key_clear(KEY_PROG3); break; - default: goto ignore; } break; @@ -490,12 +325,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel set_bit(EV_REP, input->evbit); switch(usage->hid & HID_USAGE) { - case 0x003: - /* The fn key on Apple PowerBooks */ - map_key_clear(KEY_FN); - hidinput_pb_setup(input); - break; - + case 0x003: map_key_clear(KEY_FN); break; default: goto ignore; } break; @@ -652,9 +482,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; } - if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value)) - return; - if (usage->hat_min < usage->hat_max || usage->hat_dir) { int hat_dir = usage->hat_dir; if (!hat_dir) @@ -697,7 +524,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; } - if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ + if((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ return; input_event(input, usage->type, usage->code, value); diff --git a/trunk/drivers/usb/input/hid.h b/trunk/drivers/usb/input/hid.h index 8b0d4346ce9c..ee48a2276104 100644 --- a/trunk/drivers/usb/input/hid.h +++ b/trunk/drivers/usb/input/hid.h @@ -235,20 +235,17 @@ struct hid_item { * HID device quirks. */ -#define HID_QUIRK_INVERT 0x00000001 -#define HID_QUIRK_NOTOUCH 0x00000002 -#define HID_QUIRK_IGNORE 0x00000004 -#define HID_QUIRK_NOGET 0x00000008 -#define HID_QUIRK_HIDDEV 0x00000010 -#define HID_QUIRK_BADPAD 0x00000020 -#define HID_QUIRK_MULTI_INPUT 0x00000040 -#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 -#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 -#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 -#define HID_QUIRK_2WHEEL_POWERMOUSE 0x00000400 -#define HID_QUIRK_CYMOTION 0x00000800 -#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 -#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 +#define HID_QUIRK_INVERT 0x001 +#define HID_QUIRK_NOTOUCH 0x002 +#define HID_QUIRK_IGNORE 0x004 +#define HID_QUIRK_NOGET 0x008 +#define HID_QUIRK_HIDDEV 0x010 +#define HID_QUIRK_BADPAD 0x020 +#define HID_QUIRK_MULTI_INPUT 0x040 +#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x080 +#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x100 +#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x200 +#define HID_QUIRK_2WHEEL_POWERMOUSE 0x400 /* * This is the global environment of the parser. This information is @@ -434,11 +431,6 @@ struct hid_device { /* device report descriptor */ void (*ff_exit)(struct hid_device*); /* Called by hid_exit_ff(hid) */ int (*ff_event)(struct hid_device *hid, struct input_dev *input, unsigned int type, unsigned int code, int value); - -#ifdef CONFIG_USB_HIDINPUT_POWERBOOK - unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; - unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; -#endif }; #define HID_GLOBAL_STACK_SIZE 4 diff --git a/trunk/drivers/usb/input/pid.c b/trunk/drivers/usb/input/pid.c index d9d9f656b8c9..19e015d171aa 100644 --- a/trunk/drivers/usb/input/pid.c +++ b/trunk/drivers/usb/input/pid.c @@ -259,7 +259,7 @@ static int hid_pid_upload_effect(struct input_dev *dev, int hid_pid_init(struct hid_device *hid) { struct hid_ff_pid *private; - struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); + struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list); struct input_dev *input_dev = hidinput->input; private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL); diff --git a/trunk/drivers/usb/input/wacom.c b/trunk/drivers/usb/input/wacom.c index d3e15df9e815..48df4cfd5a42 100644 --- a/trunk/drivers/usb/input/wacom.c +++ b/trunk/drivers/usb/input/wacom.c @@ -95,7 +95,7 @@ MODULE_LICENSE(DRIVER_LICENSE); enum { PENPARTNER = 0, GRAPHIRE, - WACOM_G4, + G4, PL, INTUOS, INTUOS3, @@ -373,7 +373,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) case 2: /* Mouse with wheel */ input_report_key(dev, BTN_MIDDLE, data[1] & 0x04); - if (wacom->features->type == WACOM_G4) { + if (wacom->features->type == G4) { rw = data[7] & 0x04 ? -(data[7] & 0x03) : (data[7] & 0x03); input_report_rel(dev, REL_WHEEL, rw); } else @@ -385,7 +385,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) id = CURSOR_DEVICE_ID; input_report_key(dev, BTN_LEFT, data[1] & 0x01); input_report_key(dev, BTN_RIGHT, data[1] & 0x02); - if (wacom->features->type == WACOM_G4) + if (wacom->features->type == G4) input_report_abs(dev, ABS_DISTANCE, data[6]); else input_report_abs(dev, ABS_DISTANCE, data[7]); @@ -410,7 +410,7 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs) input_sync(dev); /* send pad data */ - if (wacom->features->type == WACOM_G4) { + if (wacom->features->type == G4) { /* fist time sending pad data */ if (wacom->tool[1] != BTN_TOOL_FINGER) { wacom->id[1] = 0; @@ -713,8 +713,8 @@ static struct wacom_features wacom_features[] = { { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 32, GRAPHIRE, wacom_graphire_irq }, { "Wacom Graphire3", 8, 10208, 7424, 511, 32, GRAPHIRE, wacom_graphire_irq }, { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 32, GRAPHIRE, wacom_graphire_irq }, - { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, WACOM_G4, wacom_graphire_irq }, - { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, WACOM_G4, wacom_graphire_irq }, + { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 32, G4, wacom_graphire_irq }, + { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 32, G4, wacom_graphire_irq }, { "Wacom Volito", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, { "Wacom PenStation2", 8, 3250, 2320, 255, 32, GRAPHIRE, wacom_graphire_irq }, { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 32, GRAPHIRE, wacom_graphire_irq }, @@ -859,7 +859,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0); switch (wacom->features->type) { - case WACOM_G4: + case G4: input_dev->evbit[0] |= BIT(EV_MSC); input_dev->mscbit[0] |= BIT(MSC_SERIAL); input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); diff --git a/trunk/fs/proc/proc_devtree.c b/trunk/fs/proc/proc_devtree.c index 9bdd077d6f55..fb117b74809e 100644 --- a/trunk/fs/proc/proc_devtree.c +++ b/trunk/fs/proc/proc_devtree.c @@ -81,30 +81,6 @@ void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop __proc_device_tree_add_prop(pde, prop); } -void proc_device_tree_remove_prop(struct proc_dir_entry *pde, - struct property *prop) -{ - remove_proc_entry(prop->name, pde); -} - -void proc_device_tree_update_prop(struct proc_dir_entry *pde, - struct property *newprop, - struct property *oldprop) -{ - struct proc_dir_entry *ent; - - for (ent = pde->subdir; ent != NULL; ent = ent->next) - if (ent->data == oldprop) - break; - if (ent == NULL) { - printk(KERN_WARNING "device-tree: property \"%s\" " - " does not exist\n", oldprop->name); - } else { - ent->data = newprop; - ent->size = newprop->length; - } -} - /* * Process a node, adding entries for its children and its properties. */ diff --git a/trunk/include/asm-powerpc/atomic.h b/trunk/include/asm-powerpc/atomic.h index 147a38dcc766..248f9aec959c 100644 --- a/trunk/include/asm-powerpc/atomic.h +++ b/trunk/include/asm-powerpc/atomic.h @@ -36,7 +36,7 @@ static __inline__ int atomic_add_return(int a, atomic_t *v) int t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: lwarx %0,0,%2 # atomic_add_return\n\ add %0,%1,%0\n" PPC405_ERR77(0,%2) @@ -72,7 +72,7 @@ static __inline__ int atomic_sub_return(int a, atomic_t *v) int t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: lwarx %0,0,%2 # atomic_sub_return\n\ subf %0,%1,%0\n" PPC405_ERR77(0,%2) @@ -106,7 +106,7 @@ static __inline__ int atomic_inc_return(atomic_t *v) int t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: lwarx %0,0,%1 # atomic_inc_return\n\ addic %0,%0,1\n" PPC405_ERR77(0,%1) @@ -150,7 +150,7 @@ static __inline__ int atomic_dec_return(atomic_t *v) int t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: lwarx %0,0,%1 # atomic_dec_return\n\ addic %0,%0,-1\n" PPC405_ERR77(0,%1) @@ -176,19 +176,19 @@ static __inline__ int atomic_dec_return(atomic_t *v) * Atomically adds @a to @v, so long as it was not @u. * Returns non-zero if @v was not @u, and zero otherwise. */ -#define atomic_add_unless(v, a, u) \ -({ \ - int c, old; \ - c = atomic_read(v); \ - for (;;) { \ - if (unlikely(c == (u))) \ - break; \ - old = atomic_cmpxchg((v), c, c + (a)); \ - if (likely(old == c)) \ - break; \ - c = old; \ - } \ - c != (u); \ +#define atomic_add_unless(v, a, u) \ +({ \ + int c, old; \ + c = atomic_read(v); \ + for (;;) { \ + if (unlikely(c == (u))) \ + break; \ + old = atomic_cmpxchg((v), c, c + (a)); \ + if (likely(old == c)) \ + break; \ + c = old; \ + } \ + c != (u); \ }) #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) @@ -204,7 +204,7 @@ static __inline__ int atomic_dec_if_positive(atomic_t *v) int t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: lwarx %0,0,%1 # atomic_dec_if_positive\n\ addic. %0,%0,-1\n\ blt- 2f\n" @@ -253,7 +253,7 @@ static __inline__ long atomic64_add_return(long a, atomic64_t *v) long t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: ldarx %0,0,%2 # atomic64_add_return\n\ add %0,%1,%0\n\ stdcx. %0,0,%2 \n\ @@ -287,7 +287,7 @@ static __inline__ long atomic64_sub_return(long a, atomic64_t *v) long t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: ldarx %0,0,%2 # atomic64_sub_return\n\ subf %0,%1,%0\n\ stdcx. %0,0,%2 \n\ @@ -319,7 +319,7 @@ static __inline__ long atomic64_inc_return(atomic64_t *v) long t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: ldarx %0,0,%1 # atomic64_inc_return\n\ addic %0,%0,1\n\ stdcx. %0,0,%1 \n\ @@ -361,7 +361,7 @@ static __inline__ long atomic64_dec_return(atomic64_t *v) long t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: ldarx %0,0,%1 # atomic64_dec_return\n\ addic %0,%0,-1\n\ stdcx. %0,0,%1\n\ @@ -386,7 +386,7 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v) long t; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: ldarx %0,0,%1 # atomic64_dec_if_positive\n\ addic. %0,%0,-1\n\ blt- 2f\n\ diff --git a/trunk/include/asm-powerpc/bitops.h b/trunk/include/asm-powerpc/bitops.h index bf6941a810b8..1996eaa8aeae 100644 --- a/trunk/include/asm-powerpc/bitops.h +++ b/trunk/include/asm-powerpc/bitops.h @@ -112,7 +112,7 @@ static __inline__ int test_and_set_bit(unsigned long nr, unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1:" PPC_LLARX "%0,0,%3 # test_and_set_bit\n" "or %1,%0,%2 \n" PPC405_ERR77(0,%3) @@ -134,7 +134,7 @@ static __inline__ int test_and_clear_bit(unsigned long nr, unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1:" PPC_LLARX "%0,0,%3 # test_and_clear_bit\n" "andc %1,%0,%2 \n" PPC405_ERR77(0,%3) @@ -156,7 +156,7 @@ static __inline__ int test_and_change_bit(unsigned long nr, unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1:" PPC_LLARX "%0,0,%3 # test_and_change_bit\n" "xor %1,%0,%2 \n" PPC405_ERR77(0,%3) diff --git a/trunk/include/asm-powerpc/cputable.h b/trunk/include/asm-powerpc/cputable.h index 64210549f56b..ef6ead34a773 100644 --- a/trunk/include/asm-powerpc/cputable.h +++ b/trunk/include/asm-powerpc/cputable.h @@ -19,7 +19,6 @@ #define PPC_FEATURE_POWER5 0x00040000 #define PPC_FEATURE_POWER5_PLUS 0x00020000 #define PPC_FEATURE_CELL 0x00010000 -#define PPC_FEATURE_BOOKE 0x00008000 #ifdef __KERNEL__ #ifndef __ASSEMBLY__ @@ -32,11 +31,11 @@ struct cpu_spec; typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec); enum powerpc_oprofile_type { - PPC_OPROFILE_INVALID = 0, - PPC_OPROFILE_RS64 = 1, - PPC_OPROFILE_POWER4 = 2, - PPC_OPROFILE_G4 = 3, - PPC_OPROFILE_BOOKE = 4, + INVALID = 0, + RS64 = 1, + POWER4 = 2, + G4 = 3, + BOOKE = 4, }; struct cpu_spec { @@ -65,9 +64,6 @@ struct cpu_spec { /* Processor specific oprofile operations */ enum powerpc_oprofile_type oprofile_type; - - /* Name of processor class, for the ELF AT_PLATFORM entry */ - char *platform; }; extern struct cpu_spec *cur_cpu_spec; diff --git a/trunk/include/asm-powerpc/elf.h b/trunk/include/asm-powerpc/elf.h index 94d228f9c6ac..45f2af6f89c4 100644 --- a/trunk/include/asm-powerpc/elf.h +++ b/trunk/include/asm-powerpc/elf.h @@ -221,19 +221,21 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); instruction set this cpu supports. This could be done in userspace, but it's not easy, and we've already done it here. */ # define ELF_HWCAP (cur_cpu_spec->cpu_user_features) - -/* This yields a string that ld.so will use to load implementation - specific libraries for optimization. This is more specific in - intent than poking at uname or /proc/cpuinfo. */ - -#define ELF_PLATFORM (cur_cpu_spec->platform) - #ifdef __powerpc64__ # define ELF_PLAT_INIT(_r, load_addr) do { \ _r->gpr[2] = load_addr; \ } while (0) #endif /* __powerpc64__ */ +/* This yields a string that ld.so will use to load implementation + specific libraries for optimization. This is more specific in + intent than poking at uname or /proc/cpuinfo. + + For the moment, we have only optimizations for the Intel generations, + but that could change... */ + +#define ELF_PLATFORM (NULL) + #ifdef __KERNEL__ #ifdef __powerpc64__ diff --git a/trunk/include/asm-powerpc/futex.h b/trunk/include/asm-powerpc/futex.h index 39e85f320a76..f0319d50b129 100644 --- a/trunk/include/asm-powerpc/futex.h +++ b/trunk/include/asm-powerpc/futex.h @@ -11,7 +11,7 @@ #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ __asm__ __volatile ( \ - LWSYNC_ON_SMP \ + SYNC_ON_SMP \ "1: lwarx %0,0,%2\n" \ insn \ PPC405_ERR77(0, %2) \ diff --git a/trunk/include/asm-powerpc/hvcall.h b/trunk/include/asm-powerpc/hvcall.h index 38ca9ad6110d..da7af5a720e0 100644 --- a/trunk/include/asm-powerpc/hvcall.h +++ b/trunk/include/asm-powerpc/hvcall.h @@ -6,10 +6,7 @@ #define H_Success 0 #define H_Busy 1 /* Hardware busy -- retry later */ -#define H_Closed 2 /* Resource closed */ #define H_Constrained 4 /* Resource request constrained to max allowed */ -#define H_InProgress 14 /* Kind of like busy */ -#define H_Continue 18 /* Returned from H_Join on success */ #define H_LongBusyStartRange 9900 /* Start of long busy range */ #define H_LongBusyOrder1msec 9900 /* Long busy, hint that 1msec is a good time to retry */ #define H_LongBusyOrder10msec 9901 /* Long busy, hint that 10msec is a good time to retry */ @@ -117,8 +114,6 @@ #define H_REGISTER_VTERM 0x154 #define H_FREE_VTERM 0x158 #define H_POLL_PENDING 0x1D8 -#define H_JOIN 0x298 -#define H_ENABLE_CRQ 0x2B0 #ifndef __ASSEMBLY__ diff --git a/trunk/include/asm-powerpc/lppaca.h b/trunk/include/asm-powerpc/lppaca.h index cd9f11f1ef14..ff82ea7c4829 100644 --- a/trunk/include/asm-powerpc/lppaca.h +++ b/trunk/include/asm-powerpc/lppaca.h @@ -29,9 +29,7 @@ //---------------------------------------------------------------------------- #include -/* The Hypervisor barfs if the lppaca crosses a page boundary. A 1k - * alignment is sufficient to prevent this */ -struct __attribute__((__aligned__(0x400))) lppaca { +struct lppaca { //============================================================================= // CACHE_LINE_1 0x0000 - 0x007F Contains read-only data // NOTE: The xDynXyz fields are fields that will be dynamically changed by @@ -131,7 +129,5 @@ struct __attribute__((__aligned__(0x400))) lppaca { u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF }; -extern struct lppaca lppaca[]; - #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_LPPACA_H */ diff --git a/trunk/include/asm-powerpc/paca.h b/trunk/include/asm-powerpc/paca.h index c9add8f1ad94..a64b4d425dab 100644 --- a/trunk/include/asm-powerpc/paca.h +++ b/trunk/include/asm-powerpc/paca.h @@ -23,7 +23,6 @@ register struct paca_struct *local_paca asm("r13"); #define get_paca() local_paca -#define get_lppaca() (get_paca()->lppaca_ptr) struct task_struct; @@ -96,6 +95,19 @@ struct paca_struct { u64 saved_r1; /* r1 save for RTAS calls */ u64 saved_msr; /* MSR saved here by enter_rtas */ u8 proc_enabled; /* irq soft-enable flag */ + + /* + * iSeries structure which the hypervisor knows about - + * this structure should not cross a page boundary. + * The vpa_init/register_vpa call is now known to fail if the + * lppaca structure crosses a page boundary. + * The lppaca is also used on POWER5 pSeries boxes. + * The lppaca is 640 bytes long, and cannot readily change + * since the hypervisor knows its layout, so a 1kB + * alignment will suffice to ensure that it doesn't + * cross a page boundary. + */ + struct lppaca lppaca __attribute__((__aligned__(0x400))); }; extern struct paca_struct paca[]; diff --git a/trunk/include/asm-powerpc/ppc_asm.h b/trunk/include/asm-powerpc/ppc_asm.h index ab8688d39024..0dc798d46ea4 100644 --- a/trunk/include/asm-powerpc/ppc_asm.h +++ b/trunk/include/asm-powerpc/ppc_asm.h @@ -156,56 +156,52 @@ GLUE(.,name): #endif /* - * LOAD_REG_IMMEDIATE(rn, expr) - * Loads the value of the constant expression 'expr' into register 'rn' - * using immediate instructions only. Use this when it's important not - * to reference other data (i.e. on ppc64 when the TOC pointer is not - * valid). + * LOADADDR( rn, name ) + * loads the address of 'name' into 'rn' * - * LOAD_REG_ADDR(rn, name) - * Loads the address of label 'name' into register 'rn'. Use this when - * you don't particularly need immediate instructions only, but you need - * the whole address in one register (e.g. it's a structure address and - * you want to access various offsets within it). On ppc32 this is - * identical to LOAD_REG_IMMEDIATE. - * - * LOAD_REG_ADDRBASE(rn, name) - * ADDROFF(name) - * LOAD_REG_ADDRBASE loads part of the address of label 'name' into - * register 'rn'. ADDROFF(name) returns the remainder of the address as - * a constant expression. ADDROFF(name) is a signed expression < 16 bits - * in size, so is suitable for use directly as an offset in load and store - * instructions. Use this when loading/storing a single word or less as: - * LOAD_REG_ADDRBASE(rX, name) - * ld rY,ADDROFF(name)(rX) + * LOADBASE( rn, name ) + * loads the address (possibly without the low 16 bits) of 'name' into 'rn' + * suitable for base+disp addressing */ #ifdef __powerpc64__ -#define LOAD_REG_IMMEDIATE(reg,expr) \ - lis (reg),(expr)@highest; \ - ori (reg),(reg),(expr)@higher; \ - rldicr (reg),(reg),32,31; \ - oris (reg),(reg),(expr)@h; \ - ori (reg),(reg),(expr)@l; - -#define LOAD_REG_ADDR(reg,name) \ - ld (reg),name@got(r2) - -#define LOAD_REG_ADDRBASE(reg,name) LOAD_REG_ADDR(reg,name) -#define ADDROFF(name) 0 +#define LOADADDR(rn,name) \ + lis rn,name##@highest; \ + ori rn,rn,name##@higher; \ + rldicr rn,rn,32,31; \ + oris rn,rn,name##@h; \ + ori rn,rn,name##@l + +#define LOADBASE(rn,name) \ + ld rn,name@got(r2) + +#define OFF(name) 0 + +#define SET_REG_TO_CONST(reg, value) \ + lis reg,(((value)>>48)&0xFFFF); \ + ori reg,reg,(((value)>>32)&0xFFFF); \ + rldicr reg,reg,32,31; \ + oris reg,reg,(((value)>>16)&0xFFFF); \ + ori reg,reg,((value)&0xFFFF); + +#define SET_REG_TO_LABEL(reg, label) \ + lis reg,(label)@highest; \ + ori reg,reg,(label)@higher; \ + rldicr reg,reg,32,31; \ + oris reg,reg,(label)@h; \ + ori reg,reg,(label)@l; /* offsets for stack frame layout */ #define LRSAVE 16 #else /* 32-bit */ +#define LOADADDR(rn,name) \ + lis rn,name@ha; \ + addi rn,rn,name@l -#define LOAD_REG_IMMEDIATE(reg,expr) \ - lis (reg),(expr)@ha; \ - addi (reg),(reg),(expr)@l; - -#define LOAD_REG_ADDR(reg,name) LOAD_REG_IMMEDIATE(reg, name) +#define LOADBASE(rn,name) \ + lis rn,name@ha -#define LOAD_REG_ADDRBASE(reg, name) lis (reg),name@ha -#define ADDROFF(name) name@l +#define OFF(name) name@l /* offsets for stack frame layout */ #define LRSAVE 4 diff --git a/trunk/include/asm-powerpc/prom.h b/trunk/include/asm-powerpc/prom.h index 5b2bd4eefb01..329e9bf62260 100644 --- a/trunk/include/asm-powerpc/prom.h +++ b/trunk/include/asm-powerpc/prom.h @@ -87,7 +87,6 @@ struct device_node { char *full_name; struct property *properties; - struct property *deadprops; /* removed properties */ struct device_node *parent; struct device_node *child; struct device_node *sibling; @@ -136,9 +135,6 @@ extern struct device_node *of_find_all_nodes(struct device_node *prev); extern struct device_node *of_get_parent(const struct device_node *node); extern struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev); -extern struct property *of_find_property(struct device_node *np, - const char *name, - int *lenp); extern struct device_node *of_node_get(struct device_node *node); extern void of_node_put(struct device_node *node); @@ -168,10 +164,6 @@ extern int prom_n_size_cells(struct device_node* np); extern int prom_n_intr_cells(struct device_node* np); extern void prom_get_irq_senses(unsigned char *senses, int off, int max); extern int prom_add_property(struct device_node* np, struct property* prop); -extern int prom_remove_property(struct device_node *np, struct property *prop); -extern int prom_update_property(struct device_node *np, - struct property *newprop, - struct property *oldprop); #ifdef CONFIG_PPC32 /* diff --git a/trunk/include/asm-powerpc/spinlock.h b/trunk/include/asm-powerpc/spinlock.h index 895cb6d3a42a..754900901cd8 100644 --- a/trunk/include/asm-powerpc/spinlock.h +++ b/trunk/include/asm-powerpc/spinlock.h @@ -46,7 +46,7 @@ static __inline__ unsigned long __spin_trylock(raw_spinlock_t *lock) token = LOCK_TOKEN; __asm__ __volatile__( -"1: lwarx %0,0,%2\n\ +"1: lwarx %0,0,%2 # __spin_trylock\n\ cmpwi 0,%0,0\n\ bne- 2f\n\ stwcx. %1,0,%2\n\ @@ -80,7 +80,7 @@ static int __inline__ __raw_spin_trylock(raw_spinlock_t *lock) #if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES) /* We only yield to the hypervisor if we are in shared processor mode */ -#define SHARED_PROCESSOR (get_lppaca()->shared_proc) +#define SHARED_PROCESSOR (get_paca()->lppaca.shared_proc) extern void __spin_yield(raw_spinlock_t *lock); extern void __rw_yield(raw_rwlock_t *lock); #else /* SPLPAR || ISERIES */ @@ -124,8 +124,8 @@ static void __inline__ __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long static __inline__ void __raw_spin_unlock(raw_spinlock_t *lock) { - __asm__ __volatile__("# __raw_spin_unlock\n\t" - LWSYNC_ON_SMP: : :"memory"); + __asm__ __volatile__(SYNC_ON_SMP" # __raw_spin_unlock" + : : :"memory"); lock->slock = 0; } @@ -167,7 +167,7 @@ static long __inline__ __read_trylock(raw_rwlock_t *rw) long tmp; __asm__ __volatile__( -"1: lwarx %0,0,%1\n" +"1: lwarx %0,0,%1 # read_trylock\n" __DO_SIGN_EXTEND " addic. %0,%0,1\n\ ble- 2f\n" @@ -192,7 +192,7 @@ static __inline__ long __write_trylock(raw_rwlock_t *rw) token = WRLOCK_TOKEN; __asm__ __volatile__( -"1: lwarx %0,0,%2\n\ +"1: lwarx %0,0,%2 # write_trylock\n\ cmpwi 0,%0,0\n\ bne- 2f\n" PPC405_ERR77(0,%1) @@ -249,9 +249,8 @@ static void __inline__ __raw_read_unlock(raw_rwlock_t *rw) long tmp; __asm__ __volatile__( - "# read_unlock\n\t" - LWSYNC_ON_SMP -"1: lwarx %0,0,%1\n\ + "eieio # read_unlock\n\ +1: lwarx %0,0,%1\n\ addic %0,%0,-1\n" PPC405_ERR77(0,%1) " stwcx. %0,0,%1\n\ @@ -263,8 +262,8 @@ static void __inline__ __raw_read_unlock(raw_rwlock_t *rw) static __inline__ void __raw_write_unlock(raw_rwlock_t *rw) { - __asm__ __volatile__("# write_unlock\n\t" - LWSYNC_ON_SMP: : :"memory"); + __asm__ __volatile__(SYNC_ON_SMP" # write_unlock" + : : :"memory"); rw->lock = 0; } diff --git a/trunk/include/asm-powerpc/synch.h b/trunk/include/asm-powerpc/synch.h index c90d9d9aae72..794870ab8fd3 100644 --- a/trunk/include/asm-powerpc/synch.h +++ b/trunk/include/asm-powerpc/synch.h @@ -2,8 +2,6 @@ #define _ASM_POWERPC_SYNCH_H #ifdef __KERNEL__ -#include - #ifdef __powerpc64__ #define __SUBARCH_HAS_LWSYNC #endif @@ -14,12 +12,20 @@ # define LWSYNC sync #endif + +/* + * Arguably the bitops and *xchg operations don't imply any memory barrier + * or SMP ordering, but in fact a lot of drivers expect them to imply + * both, since they do on x86 cpus. + */ #ifdef CONFIG_SMP +#define EIEIO_ON_SMP "eieio\n" #define ISYNC_ON_SMP "\n\tisync" -#define LWSYNC_ON_SMP __stringify(LWSYNC) "\n" +#define SYNC_ON_SMP __stringify(LWSYNC) "\n" #else +#define EIEIO_ON_SMP #define ISYNC_ON_SMP -#define LWSYNC_ON_SMP +#define SYNC_ON_SMP #endif static inline void eieio(void) @@ -32,5 +38,14 @@ static inline void isync(void) __asm__ __volatile__ ("isync" : : : "memory"); } +#ifdef CONFIG_SMP +#define eieio_on_smp() eieio() +#define isync_on_smp() isync() +#else +#define eieio_on_smp() __asm__ __volatile__("": : :"memory") +#define isync_on_smp() __asm__ __volatile__("": : :"memory") +#endif + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_SYNCH_H */ + diff --git a/trunk/include/asm-powerpc/system.h b/trunk/include/asm-powerpc/system.h index d9bf53653b10..9b822afa7d0e 100644 --- a/trunk/include/asm-powerpc/system.h +++ b/trunk/include/asm-powerpc/system.h @@ -212,7 +212,7 @@ __xchg_u32(volatile void *p, unsigned long val) unsigned long prev; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: lwarx %0,0,%2 \n" PPC405_ERR77(0,%2) " stwcx. %3,0,%2 \n\ @@ -232,7 +232,7 @@ __xchg_u64(volatile void *p, unsigned long val) unsigned long prev; __asm__ __volatile__( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: ldarx %0,0,%2 \n" PPC405_ERR77(0,%2) " stdcx. %3,0,%2 \n\ @@ -287,7 +287,7 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new) unsigned int prev; __asm__ __volatile__ ( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: lwarx %0,0,%2 # __cmpxchg_u32\n\ cmpw 0,%0,%3\n\ bne- 2f\n" @@ -311,7 +311,7 @@ __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new) unsigned long prev; __asm__ __volatile__ ( - LWSYNC_ON_SMP + EIEIO_ON_SMP "1: ldarx %0,0,%2 # __cmpxchg_u64\n\ cmpd 0,%0,%3\n\ bne- 2f\n\ diff --git a/trunk/include/asm-powerpc/time.h b/trunk/include/asm-powerpc/time.h index baddc9ab57ad..d9b86a17271b 100644 --- a/trunk/include/asm-powerpc/time.h +++ b/trunk/include/asm-powerpc/time.h @@ -175,10 +175,11 @@ static inline void set_dec(int val) set_dec_cpu6(val); #else #ifdef CONFIG_PPC_ISERIES + struct paca_struct *lpaca = get_paca(); int cur_dec; - if (get_lppaca()->shared_proc) { - get_lppaca()->virtual_decr = val; + if (lpaca->lppaca.shared_proc) { + lpaca->lppaca.virtual_decr = val; cur_dec = get_dec(); if (cur_dec > val) HvCall_setVirtualDecr(); diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index 323924edb26a..e6ee2d95da7a 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -216,7 +216,6 @@ extern void dump_stack(void); ((unsigned char *)&addr)[1], \ ((unsigned char *)&addr)[2], \ ((unsigned char *)&addr)[3] -#define NIPQUAD_FMT "%u.%u.%u.%u" #define NIP6(addr) \ ntohs((addr).s6_addr16[0]), \ @@ -227,7 +226,6 @@ extern void dump_stack(void); ntohs((addr).s6_addr16[5]), \ ntohs((addr).s6_addr16[6]), \ ntohs((addr).s6_addr16[7]) -#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" #if defined(__LITTLE_ENDIAN) #define HIPQUAD(addr) \ diff --git a/trunk/include/linux/netfilter/nf_conntrack_common.h b/trunk/include/linux/netfilter/nf_conntrack_common.h index 3ff88c878308..6d39b518486b 100644 --- a/trunk/include/linux/netfilter/nf_conntrack_common.h +++ b/trunk/include/linux/netfilter/nf_conntrack_common.h @@ -154,9 +154,6 @@ struct ip_conntrack_stat unsigned int expect_delete; }; -/* call to create an explicit dependency on nf_conntrack. */ -extern void need_conntrack(void); - #endif /* __KERNEL__ */ #endif /* _NF_CONNTRACK_COMMON_H */ diff --git a/trunk/include/linux/netfilter/x_tables.h b/trunk/include/linux/netfilter/x_tables.h deleted file mode 100644 index 472f04834809..000000000000 --- a/trunk/include/linux/netfilter/x_tables.h +++ /dev/null @@ -1,224 +0,0 @@ -#ifndef _X_TABLES_H -#define _X_TABLES_H - -#define XT_FUNCTION_MAXNAMELEN 30 -#define XT_TABLE_MAXNAMELEN 32 - -/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision - * kernel supports, if >= revision. */ -struct xt_get_revision -{ - char name[XT_FUNCTION_MAXNAMELEN-1]; - - u_int8_t revision; -}; - -/* CONTINUE verdict for targets */ -#define XT_CONTINUE 0xFFFFFFFF - -/* For standard target */ -#define XT_RETURN (-NF_REPEAT - 1) - -#define XT_ALIGN(s) (((s) + (__alignof__(void *)-1)) & ~(__alignof__(void *)-1)) - -/* Standard return verdict, or do jump. */ -#define XT_STANDARD_TARGET "" -/* Error verdict. */ -#define XT_ERROR_TARGET "ERROR" - -/* - * New IP firewall options for [gs]etsockopt at the RAW IP level. - * Unlike BSD Linux inherits IP options so you don't have to use a raw - * socket for this. Instead we check rights in the calls. */ -#define XT_BASE_CTL 64 /* base for firewall socket options */ - -#define XT_SO_SET_REPLACE (XT_BASE_CTL) -#define XT_SO_SET_ADD_COUNTERS (XT_BASE_CTL + 1) -#define XT_SO_SET_MAX XT_SO_SET_ADD_COUNTERS - -#define XT_SO_GET_INFO (XT_BASE_CTL) -#define XT_SO_GET_ENTRIES (XT_BASE_CTL + 1) -#define XT_SO_GET_REVISION_MATCH (XT_BASE_CTL + 2) -#define XT_SO_GET_REVISION_TARGET (XT_BASE_CTL + 3) -#define XT_SO_GET_MAX XT_SO_GET_REVISION_TARGET - -#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) -#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) - -struct xt_counters -{ - u_int64_t pcnt, bcnt; /* Packet and byte counters */ -}; - -/* The argument to IPT_SO_ADD_COUNTERS. */ -struct xt_counters_info -{ - /* Which table. */ - char name[XT_TABLE_MAXNAMELEN]; - - unsigned int num_counters; - - /* The counters (actually `number' of these). */ - struct xt_counters counters[0]; -}; - -#define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ - -#ifdef __KERNEL__ - -#include - -#define ASSERT_READ_LOCK(x) -#define ASSERT_WRITE_LOCK(x) -#include - -struct xt_match -{ - struct list_head list; - - const char name[XT_FUNCTION_MAXNAMELEN-1]; - - u_int8_t revision; - - /* Return true or false: return FALSE and set *hotdrop = 1 to - force immediate packet drop. */ - /* Arguments changed since 2.6.9, as this must now handle - non-linear skb, using skb_header_pointer and - skb_ip_make_writable. */ - int (*match)(const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const void *matchinfo, - int offset, - unsigned int protoff, - int *hotdrop); - - /* Called when user tries to insert an entry of this type. */ - /* Should return true or false. */ - int (*checkentry)(const char *tablename, - const void *ip, - void *matchinfo, - unsigned int matchinfosize, - unsigned int hook_mask); - - /* Called when entry of this type deleted. */ - void (*destroy)(void *matchinfo, unsigned int matchinfosize); - - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ - struct module *me; -}; - -/* Registration hooks for targets. */ -struct xt_target -{ - struct list_head list; - - const char name[XT_FUNCTION_MAXNAMELEN-1]; - - u_int8_t revision; - - /* Returns verdict. Argument order changed since 2.6.9, as this - must now handle non-linear skbs, using skb_copy_bits and - skb_ip_make_writable. */ - unsigned int (*target)(struct sk_buff **pskb, - const struct net_device *in, - const struct net_device *out, - unsigned int hooknum, - const void *targinfo, - void *userdata); - - /* Called when user tries to insert an entry of this type: - hook_mask is a bitmask of hooks from which it can be - called. */ - /* Should return true or false. */ - int (*checkentry)(const char *tablename, - const void *entry, - void *targinfo, - unsigned int targinfosize, - unsigned int hook_mask); - - /* Called when entry of this type deleted. */ - void (*destroy)(void *targinfo, unsigned int targinfosize); - - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ - struct module *me; -}; - -/* Furniture shopping... */ -struct xt_table -{ - struct list_head list; - - /* A unique name... */ - char name[XT_TABLE_MAXNAMELEN]; - - /* What hooks you will enter on */ - unsigned int valid_hooks; - - /* Lock for the curtain */ - rwlock_t lock; - - /* Man behind the curtain... */ - //struct ip6t_table_info *private; - void *private; - - /* Set this to THIS_MODULE if you are a module, otherwise NULL */ - struct module *me; - - int af; /* address/protocol family */ -}; - -#include - -/* The table itself */ -struct xt_table_info -{ - /* Size per table */ - unsigned int size; - /* Number of entries: FIXME. --RR */ - unsigned int number; - /* Initial number of entries. Needed for module usage count */ - unsigned int initial_entries; - - /* Entry points and underflows */ - unsigned int hook_entry[NF_IP_NUMHOOKS]; - unsigned int underflow[NF_IP_NUMHOOKS]; - - /* ipt_entry tables: one per CPU */ - char *entries[NR_CPUS]; -}; - -extern int xt_register_target(int af, struct xt_target *target); -extern void xt_unregister_target(int af, struct xt_target *target); -extern int xt_register_match(int af, struct xt_match *target); -extern void xt_unregister_match(int af, struct xt_match *target); - -extern int xt_register_table(struct xt_table *table, - struct xt_table_info *bootstrap, - struct xt_table_info *newinfo); -extern void *xt_unregister_table(struct xt_table *table); - -extern struct xt_table_info *xt_replace_table(struct xt_table *table, - unsigned int num_counters, - struct xt_table_info *newinfo, - int *error); - -extern struct xt_match *xt_find_match(int af, const char *name, u8 revision); -extern struct xt_target *xt_find_target(int af, const char *name, u8 revision); -extern struct xt_target *xt_request_find_target(int af, const char *name, - u8 revision); -extern int xt_find_revision(int af, const char *name, u8 revision, int target, - int *err); - -extern struct xt_table *xt_find_table_lock(int af, const char *name); -extern void xt_table_unlock(struct xt_table *t); - -extern int xt_proto_init(int af); -extern void xt_proto_fini(int af); - -extern struct xt_table_info *xt_alloc_table_info(unsigned int size); -extern void xt_free_table_info(struct xt_table_info *info); - -#endif /* __KERNEL__ */ - -#endif /* _X_TABLES_H */ diff --git a/trunk/include/linux/netfilter/xt_CLASSIFY.h b/trunk/include/linux/netfilter/xt_CLASSIFY.h deleted file mode 100644 index 58111355255d..000000000000 --- a/trunk/include/linux/netfilter/xt_CLASSIFY.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _XT_CLASSIFY_H -#define _XT_CLASSIFY_H - -struct xt_classify_target_info { - u_int32_t priority; -}; - -#endif /*_XT_CLASSIFY_H */ diff --git a/trunk/include/linux/netfilter/xt_CONNMARK.h b/trunk/include/linux/netfilter/xt_CONNMARK.h deleted file mode 100644 index 9f744689fffc..000000000000 --- a/trunk/include/linux/netfilter/xt_CONNMARK.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _XT_CONNMARK_H_target -#define _XT_CONNMARK_H_target - -/* Copyright (C) 2002,2004 MARA Systems AB - * by Henrik Nordstrom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -enum { - XT_CONNMARK_SET = 0, - XT_CONNMARK_SAVE, - XT_CONNMARK_RESTORE -}; - -struct xt_connmark_target_info { - unsigned long mark; - unsigned long mask; - u_int8_t mode; -}; - -#endif /*_XT_CONNMARK_H_target*/ diff --git a/trunk/include/linux/netfilter/xt_MARK.h b/trunk/include/linux/netfilter/xt_MARK.h deleted file mode 100644 index b021e93ee5d6..000000000000 --- a/trunk/include/linux/netfilter/xt_MARK.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _XT_MARK_H_target -#define _XT_MARK_H_target - -/* Version 0 */ -struct xt_mark_target_info { - unsigned long mark; -}; - -/* Version 1 */ -enum { - XT_MARK_SET=0, - XT_MARK_AND, - XT_MARK_OR, -}; - -struct xt_mark_target_info_v1 { - unsigned long mark; - u_int8_t mode; -}; - -#endif /*_XT_MARK_H_target */ diff --git a/trunk/include/linux/netfilter/xt_NFQUEUE.h b/trunk/include/linux/netfilter/xt_NFQUEUE.h deleted file mode 100644 index 9a9af79f74d2..000000000000 --- a/trunk/include/linux/netfilter/xt_NFQUEUE.h +++ /dev/null @@ -1,16 +0,0 @@ -/* iptables module for using NFQUEUE mechanism - * - * (C) 2005 Harald Welte - * - * This software is distributed under GNU GPL v2, 1991 - * -*/ -#ifndef _XT_NFQ_TARGET_H -#define _XT_NFQ_TARGET_H - -/* target info */ -struct xt_NFQ_info { - u_int16_t queuenum; -}; - -#endif /* _XT_NFQ_TARGET_H */ diff --git a/trunk/include/linux/netfilter/xt_comment.h b/trunk/include/linux/netfilter/xt_comment.h deleted file mode 100644 index eacfedc6b5d0..000000000000 --- a/trunk/include/linux/netfilter/xt_comment.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _XT_COMMENT_H -#define _XT_COMMENT_H - -#define XT_MAX_COMMENT_LEN 256 - -struct xt_comment_info { - unsigned char comment[XT_MAX_COMMENT_LEN]; -}; - -#endif /* XT_COMMENT_H */ diff --git a/trunk/include/linux/netfilter/xt_connbytes.h b/trunk/include/linux/netfilter/xt_connbytes.h deleted file mode 100644 index c022c989754d..000000000000 --- a/trunk/include/linux/netfilter/xt_connbytes.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _XT_CONNBYTES_H -#define _XT_CONNBYTES_H - -enum xt_connbytes_what { - XT_CONNBYTES_PKTS, - XT_CONNBYTES_BYTES, - XT_CONNBYTES_AVGPKT, -}; - -enum xt_connbytes_direction { - XT_CONNBYTES_DIR_ORIGINAL, - XT_CONNBYTES_DIR_REPLY, - XT_CONNBYTES_DIR_BOTH, -}; - -struct xt_connbytes_info -{ - struct { - aligned_u64 from; /* count to be matched */ - aligned_u64 to; /* count to be matched */ - } count; - u_int8_t what; /* ipt_connbytes_what */ - u_int8_t direction; /* ipt_connbytes_direction */ -}; -#endif diff --git a/trunk/include/linux/netfilter/xt_connmark.h b/trunk/include/linux/netfilter/xt_connmark.h deleted file mode 100644 index c592f6ae0883..000000000000 --- a/trunk/include/linux/netfilter/xt_connmark.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _XT_CONNMARK_H -#define _XT_CONNMARK_H - -/* Copyright (C) 2002,2004 MARA Systems AB - * by Henrik Nordstrom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -struct xt_connmark_info { - unsigned long mark, mask; - u_int8_t invert; -}; - -#endif /*_XT_CONNMARK_H*/ diff --git a/trunk/include/linux/netfilter/xt_conntrack.h b/trunk/include/linux/netfilter/xt_conntrack.h deleted file mode 100644 index 34f63cf2e293..000000000000 --- a/trunk/include/linux/netfilter/xt_conntrack.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Header file for kernel module to match connection tracking information. - * GPL (C) 2001 Marc Boucher (marc@mbsi.ca). - */ - -#ifndef _XT_CONNTRACK_H -#define _XT_CONNTRACK_H - -#include -#include - -#define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) -#define XT_CONNTRACK_STATE_INVALID (1 << 0) - -#define XT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1)) -#define XT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2)) -#define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) - -/* flags, invflags: */ -#define XT_CONNTRACK_STATE 0x01 -#define XT_CONNTRACK_PROTO 0x02 -#define XT_CONNTRACK_ORIGSRC 0x04 -#define XT_CONNTRACK_ORIGDST 0x08 -#define XT_CONNTRACK_REPLSRC 0x10 -#define XT_CONNTRACK_REPLDST 0x20 -#define XT_CONNTRACK_STATUS 0x40 -#define XT_CONNTRACK_EXPIRES 0x80 - -/* This is exposed to userspace, so remains frozen in time. */ -struct ip_conntrack_old_tuple -{ - struct { - __u32 ip; - union { - __u16 all; - } u; - } src; - - struct { - __u32 ip; - union { - __u16 all; - } u; - - /* The protocol. */ - u16 protonum; - } dst; -}; - -struct xt_conntrack_info -{ - unsigned int statemask, statusmask; - - struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX]; - struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX]; - - unsigned long expires_min, expires_max; - - /* Flags word */ - u_int8_t flags; - /* Inverse flags */ - u_int8_t invflags; -}; -#endif /*_XT_CONNTRACK_H*/ diff --git a/trunk/include/linux/netfilter/xt_dccp.h b/trunk/include/linux/netfilter/xt_dccp.h deleted file mode 100644 index e0221b9d32cb..000000000000 --- a/trunk/include/linux/netfilter/xt_dccp.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _XT_DCCP_H_ -#define _XT_DCCP_H_ - -#define XT_DCCP_SRC_PORTS 0x01 -#define XT_DCCP_DEST_PORTS 0x02 -#define XT_DCCP_TYPE 0x04 -#define XT_DCCP_OPTION 0x08 - -#define XT_DCCP_VALID_FLAGS 0x0f - -struct xt_dccp_info { - u_int16_t dpts[2]; /* Min, Max */ - u_int16_t spts[2]; /* Min, Max */ - - u_int16_t flags; - u_int16_t invflags; - - u_int16_t typemask; - u_int8_t option; -}; - -#endif /* _XT_DCCP_H_ */ - diff --git a/trunk/include/linux/netfilter/xt_helper.h b/trunk/include/linux/netfilter/xt_helper.h deleted file mode 100644 index 6b42763f999d..000000000000 --- a/trunk/include/linux/netfilter/xt_helper.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _XT_HELPER_H -#define _XT_HELPER_H - -struct xt_helper_info { - int invert; - char name[30]; -}; -#endif /* _XT_HELPER_H */ diff --git a/trunk/include/linux/netfilter/xt_length.h b/trunk/include/linux/netfilter/xt_length.h deleted file mode 100644 index 7c2b439f73fe..000000000000 --- a/trunk/include/linux/netfilter/xt_length.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _XT_LENGTH_H -#define _XT_LENGTH_H - -struct xt_length_info { - u_int16_t min, max; - u_int8_t invert; -}; - -#endif /*_XT_LENGTH_H*/ diff --git a/trunk/include/linux/netfilter/xt_limit.h b/trunk/include/linux/netfilter/xt_limit.h deleted file mode 100644 index b3ce65375ecb..000000000000 --- a/trunk/include/linux/netfilter/xt_limit.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _XT_RATE_H -#define _XT_RATE_H - -/* timings are in milliseconds. */ -#define XT_LIMIT_SCALE 10000 - -/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 - seconds, or one every 59 hours. */ -struct xt_rateinfo { - u_int32_t avg; /* Average secs between packets * scale */ - u_int32_t burst; /* Period multiplier for upper limit. */ - - /* Used internally by the kernel */ - unsigned long prev; - u_int32_t credit; - u_int32_t credit_cap, cost; - - /* Ugly, ugly fucker. */ - struct xt_rateinfo *master; -}; -#endif /*_XT_RATE_H*/ diff --git a/trunk/include/linux/netfilter/xt_mac.h b/trunk/include/linux/netfilter/xt_mac.h deleted file mode 100644 index b892cdc67e06..000000000000 --- a/trunk/include/linux/netfilter/xt_mac.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _XT_MAC_H -#define _XT_MAC_H - -struct xt_mac_info { - unsigned char srcaddr[ETH_ALEN]; - int invert; -}; -#endif /*_XT_MAC_H*/ diff --git a/trunk/include/linux/netfilter/xt_mark.h b/trunk/include/linux/netfilter/xt_mark.h deleted file mode 100644 index 802dd4842caf..000000000000 --- a/trunk/include/linux/netfilter/xt_mark.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _XT_MARK_H -#define _XT_MARK_H - -struct xt_mark_info { - unsigned long mark, mask; - u_int8_t invert; -}; - -#endif /*_XT_MARK_H*/ diff --git a/trunk/include/linux/netfilter/xt_physdev.h b/trunk/include/linux/netfilter/xt_physdev.h deleted file mode 100644 index 25a7a1815b5b..000000000000 --- a/trunk/include/linux/netfilter/xt_physdev.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _XT_PHYSDEV_H -#define _XT_PHYSDEV_H - -#ifdef __KERNEL__ -#include -#endif - -#define XT_PHYSDEV_OP_IN 0x01 -#define XT_PHYSDEV_OP_OUT 0x02 -#define XT_PHYSDEV_OP_BRIDGED 0x04 -#define XT_PHYSDEV_OP_ISIN 0x08 -#define XT_PHYSDEV_OP_ISOUT 0x10 -#define XT_PHYSDEV_OP_MASK (0x20 - 1) - -struct xt_physdev_info { - char physindev[IFNAMSIZ]; - char in_mask[IFNAMSIZ]; - char physoutdev[IFNAMSIZ]; - char out_mask[IFNAMSIZ]; - u_int8_t invert; - u_int8_t bitmask; -}; - -#endif /*_XT_PHYSDEV_H*/ diff --git a/trunk/include/linux/netfilter/xt_pkttype.h b/trunk/include/linux/netfilter/xt_pkttype.h deleted file mode 100644 index f265cf52faea..000000000000 --- a/trunk/include/linux/netfilter/xt_pkttype.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _XT_PKTTYPE_H -#define _XT_PKTTYPE_H - -struct xt_pkttype_info { - int pkttype; - int invert; -}; -#endif /*_XT_PKTTYPE_H*/ diff --git a/trunk/include/linux/netfilter/xt_realm.h b/trunk/include/linux/netfilter/xt_realm.h deleted file mode 100644 index 220e87245716..000000000000 --- a/trunk/include/linux/netfilter/xt_realm.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _XT_REALM_H -#define _XT_REALM_H - -struct xt_realm_info { - u_int32_t id; - u_int32_t mask; - u_int8_t invert; -}; - -#endif /* _XT_REALM_H */ diff --git a/trunk/include/linux/netfilter/xt_sctp.h b/trunk/include/linux/netfilter/xt_sctp.h deleted file mode 100644 index b157897e7792..000000000000 --- a/trunk/include/linux/netfilter/xt_sctp.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef _XT_SCTP_H_ -#define _XT_SCTP_H_ - -#define XT_SCTP_SRC_PORTS 0x01 -#define XT_SCTP_DEST_PORTS 0x02 -#define XT_SCTP_CHUNK_TYPES 0x04 - -#define XT_SCTP_VALID_FLAGS 0x07 - -#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0])) - - -struct xt_sctp_flag_info { - u_int8_t chunktype; - u_int8_t flag; - u_int8_t flag_mask; -}; - -#define XT_NUM_SCTP_FLAGS 4 - -struct xt_sctp_info { - u_int16_t dpts[2]; /* Min, Max */ - u_int16_t spts[2]; /* Min, Max */ - - u_int32_t chunkmap[256 / sizeof (u_int32_t)]; /* Bit mask of chunks to be matched according to RFC 2960 */ - -#define SCTP_CHUNK_MATCH_ANY 0x01 /* Match if any of the chunk types are present */ -#define SCTP_CHUNK_MATCH_ALL 0x02 /* Match if all of the chunk types are present */ -#define SCTP_CHUNK_MATCH_ONLY 0x04 /* Match if these are the only chunk types present */ - - u_int32_t chunk_match_type; - struct xt_sctp_flag_info flag_info[XT_NUM_SCTP_FLAGS]; - int flag_count; - - u_int32_t flags; - u_int32_t invflags; -}; - -#define bytes(type) (sizeof(type) * 8) - -#define SCTP_CHUNKMAP_SET(chunkmap, type) \ - do { \ - chunkmap[type / bytes(u_int32_t)] |= \ - 1 << (type % bytes(u_int32_t)); \ - } while (0) - -#define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \ - do { \ - chunkmap[type / bytes(u_int32_t)] &= \ - ~(1 << (type % bytes(u_int32_t))); \ - } while (0) - -#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \ -({ \ - (chunkmap[type / bytes (u_int32_t)] & \ - (1 << (type % bytes (u_int32_t)))) ? 1: 0; \ -}) - -#define SCTP_CHUNKMAP_RESET(chunkmap) \ - do { \ - int i; \ - for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ - chunkmap[i] = 0; \ - } while (0) - -#define SCTP_CHUNKMAP_SET_ALL(chunkmap) \ - do { \ - int i; \ - for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ - chunkmap[i] = ~0; \ - } while (0) - -#define SCTP_CHUNKMAP_COPY(destmap, srcmap) \ - do { \ - int i; \ - for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ - destmap[i] = srcmap[i]; \ - } while (0) - -#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) \ -({ \ - int i; \ - int flag = 1; \ - for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \ - if (chunkmap[i]) { \ - flag = 0; \ - break; \ - } \ - } \ - flag; \ -}) - -#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) \ -({ \ - int i; \ - int flag = 1; \ - for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \ - if (chunkmap[i] != ~0) { \ - flag = 0; \ - break; \ - } \ - } \ - flag; \ -}) - -#endif /* _XT_SCTP_H_ */ - diff --git a/trunk/include/linux/netfilter/xt_state.h b/trunk/include/linux/netfilter/xt_state.h deleted file mode 100644 index c06f32edee07..000000000000 --- a/trunk/include/linux/netfilter/xt_state.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _XT_STATE_H -#define _XT_STATE_H - -#define XT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) -#define XT_STATE_INVALID (1 << 0) - -#define XT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1)) - -struct xt_state_info -{ - unsigned int statemask; -}; -#endif /*_XT_STATE_H*/ diff --git a/trunk/include/linux/netfilter/xt_string.h b/trunk/include/linux/netfilter/xt_string.h deleted file mode 100644 index 3b3419f2637d..000000000000 --- a/trunk/include/linux/netfilter/xt_string.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _XT_STRING_H -#define _XT_STRING_H - -#define XT_STRING_MAX_PATTERN_SIZE 128 -#define XT_STRING_MAX_ALGO_NAME_SIZE 16 - -struct xt_string_info -{ - u_int16_t from_offset; - u_int16_t to_offset; - char algo[XT_STRING_MAX_ALGO_NAME_SIZE]; - char pattern[XT_STRING_MAX_PATTERN_SIZE]; - u_int8_t patlen; - u_int8_t invert; - struct ts_config __attribute__((aligned(8))) *config; -}; - -#endif /*_XT_STRING_H*/ diff --git a/trunk/include/linux/netfilter/xt_tcpmss.h b/trunk/include/linux/netfilter/xt_tcpmss.h deleted file mode 100644 index e03274c4c790..000000000000 --- a/trunk/include/linux/netfilter/xt_tcpmss.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _XT_TCPMSS_MATCH_H -#define _XT_TCPMSS_MATCH_H - -struct xt_tcpmss_match_info { - u_int16_t mss_min, mss_max; - u_int8_t invert; -}; - -#endif /*_XT_TCPMSS_MATCH_H*/ diff --git a/trunk/include/linux/netfilter/xt_tcpudp.h b/trunk/include/linux/netfilter/xt_tcpudp.h deleted file mode 100644 index 78bc65f11adf..000000000000 --- a/trunk/include/linux/netfilter/xt_tcpudp.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef _XT_TCPUDP_H -#define _XT_TCPUDP_H - -/* TCP matching stuff */ -struct xt_tcp -{ - u_int16_t spts[2]; /* Source port range. */ - u_int16_t dpts[2]; /* Destination port range. */ - u_int8_t option; /* TCP Option iff non-zero*/ - u_int8_t flg_mask; /* TCP flags mask byte */ - u_int8_t flg_cmp; /* TCP flags compare byte */ - u_int8_t invflags; /* Inverse flags */ -}; - -/* Values for "inv" field in struct ipt_tcp. */ -#define XT_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ -#define XT_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ -#define XT_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ -#define XT_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ -#define XT_TCP_INV_MASK 0x0F /* All possible flags. */ - -/* UDP matching stuff */ -struct xt_udp -{ - u_int16_t spts[2]; /* Source port range. */ - u_int16_t dpts[2]; /* Destination port range. */ - u_int8_t invflags; /* Inverse flags */ -}; - -/* Values for "invflags" field in struct ipt_udp. */ -#define XT_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ -#define XT_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ -#define XT_UDP_INV_MASK 0x03 /* All possible flags. */ - - -#endif diff --git a/trunk/include/linux/netfilter_arp/arp_tables.h b/trunk/include/linux/netfilter_arp/arp_tables.h index fd21796e5131..e98a870a20be 100644 --- a/trunk/include/linux/netfilter_arp/arp_tables.h +++ b/trunk/include/linux/netfilter_arp/arp_tables.h @@ -19,12 +19,8 @@ #include #include -#include - -#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN -#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN -#define arpt_target xt_target -#define arpt_table xt_table +#define ARPT_FUNCTION_MAXNAMELEN 30 +#define ARPT_TABLE_MAXNAMELEN 32 #define ARPT_DEV_ADDR_LEN_MAX 16 @@ -95,6 +91,11 @@ struct arpt_standard_target int verdict; }; +struct arpt_counters +{ + u_int64_t pcnt, bcnt; /* Packet and byte counters */ +}; + /* Values for "flag" field in struct arpt_ip (general arp structure). * No flags defined yet. */ @@ -129,7 +130,7 @@ struct arpt_entry unsigned int comefrom; /* Packet and byte counters. */ - struct xt_counters counters; + struct arpt_counters counters; /* The matches (if any), then the target. */ unsigned char elems[0]; @@ -140,24 +141,23 @@ struct arpt_entry * Unlike BSD Linux inherits IP options so you don't have to use a raw * socket for this. Instead we check rights in the calls. */ -#define ARPT_CTL_OFFSET 32 -#define ARPT_BASE_CTL (XT_BASE_CTL+ARPT_CTL_OFFSET) +#define ARPT_BASE_CTL 96 /* base for firewall socket options */ -#define ARPT_SO_SET_REPLACE (XT_SO_SET_REPLACE+ARPT_CTL_OFFSET) -#define ARPT_SO_SET_ADD_COUNTERS (XT_SO_SET_ADD_COUNTERS+ARPT_CTL_OFFSET) -#define ARPT_SO_SET_MAX (XT_SO_SET_MAX+ARPT_CTL_OFFSET) +#define ARPT_SO_SET_REPLACE (ARPT_BASE_CTL) +#define ARPT_SO_SET_ADD_COUNTERS (ARPT_BASE_CTL + 1) +#define ARPT_SO_SET_MAX ARPT_SO_SET_ADD_COUNTERS -#define ARPT_SO_GET_INFO (XT_SO_GET_INFO+ARPT_CTL_OFFSET) -#define ARPT_SO_GET_ENTRIES (XT_SO_GET_ENTRIES+ARPT_CTL_OFFSET) -/* #define ARPT_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH */ -#define ARPT_SO_GET_REVISION_TARGET (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET) -#define ARPT_SO_GET_MAX (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET) +#define ARPT_SO_GET_INFO (ARPT_BASE_CTL) +#define ARPT_SO_GET_ENTRIES (ARPT_BASE_CTL + 1) +/* #define ARPT_SO_GET_REVISION_MATCH (ARPT_BASE_CTL + 2)*/ +#define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3) +#define ARPT_SO_GET_MAX ARPT_SO_GET_REVISION_TARGET /* CONTINUE verdict for targets */ -#define ARPT_CONTINUE XT_CONTINUE +#define ARPT_CONTINUE 0xFFFFFFFF /* For standard target */ -#define ARPT_RETURN XT_RETURN +#define ARPT_RETURN (-NF_REPEAT - 1) /* The argument to ARPT_SO_GET_INFO */ struct arpt_getinfo @@ -208,14 +208,23 @@ struct arpt_replace /* Number of counters (must be equal to current number of entries). */ unsigned int num_counters; /* The old entries' counters. */ - struct xt_counters __user *counters; + struct arpt_counters __user *counters; /* The entries (hang off end: not really an array). */ struct arpt_entry entries[0]; }; /* The argument to ARPT_SO_ADD_COUNTERS. */ -#define arpt_counters_info xt_counters_info +struct arpt_counters_info +{ + /* Which table. */ + char name[ARPT_TABLE_MAXNAMELEN]; + + unsigned int num_counters; + + /* The counters (actually `number' of these). */ + struct arpt_counters counters[0]; +}; /* The argument to ARPT_SO_GET_ENTRIES. */ struct arpt_get_entries @@ -230,10 +239,19 @@ struct arpt_get_entries struct arpt_entry entrytable[0]; }; +/* The argument to ARPT_SO_GET_REVISION_*. Returns highest revision + * kernel supports, if >= revision. */ +struct arpt_get_revision +{ + char name[ARPT_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; +}; + /* Standard return verdict, or do jump. */ -#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET +#define ARPT_STANDARD_TARGET "" /* Error verdict. */ -#define ARPT_ERROR_TARGET XT_ERROR_TARGET +#define ARPT_ERROR_TARGET "ERROR" /* Helper functions */ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e) @@ -263,8 +281,63 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e */ #ifdef __KERNEL__ -#define arpt_register_target(tgt) xt_register_target(NF_ARP, tgt) -#define arpt_unregister_target(tgt) xt_unregister_target(NF_ARP, tgt) +/* Registration hooks for targets. */ +struct arpt_target +{ + struct list_head list; + + const char name[ARPT_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; + + /* Returns verdict. */ + unsigned int (*target)(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + const void *targinfo, + void *userdata); + + /* Called when user tries to insert an entry of this type: + hook_mask is a bitmask of hooks from which it can be + called. */ + /* Should return true or false. */ + int (*checkentry)(const char *tablename, + const struct arpt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask); + + /* Called when entry of this type deleted. */ + void (*destroy)(void *targinfo, unsigned int targinfosize); + + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ + struct module *me; +}; + +extern int arpt_register_target(struct arpt_target *target); +extern void arpt_unregister_target(struct arpt_target *target); + +/* Furniture shopping... */ +struct arpt_table +{ + struct list_head list; + + /* A unique name... */ + char name[ARPT_TABLE_MAXNAMELEN]; + + /* What hooks you will enter on */ + unsigned int valid_hooks; + + /* Lock for the curtain */ + rwlock_t lock; + + /* Man behind the curtain... */ + struct arpt_table_info *private; + + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ + struct module *me; +}; extern int arpt_register_table(struct arpt_table *table, const struct arpt_replace *repl); diff --git a/trunk/include/linux/netfilter_ipv4/ip_conntrack.h b/trunk/include/linux/netfilter_ipv4/ip_conntrack.h index 215765f043e6..b3432ab59a17 100644 --- a/trunk/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/trunk/include/linux/netfilter_ipv4/ip_conntrack.h @@ -199,6 +199,9 @@ ip_conntrack_put(struct ip_conntrack *ct) nf_conntrack_put(&ct->ct_general); } +/* call to create an explicit dependency on ip_conntrack. */ +extern void need_ip_conntrack(void); + extern int invert_tuplepr(struct ip_conntrack_tuple *inverse, const struct ip_conntrack_tuple *orig); diff --git a/trunk/include/linux/netfilter_ipv4/ip_tables.h b/trunk/include/linux/netfilter_ipv4/ip_tables.h index 76ba24b68515..d19d65cf4530 100644 --- a/trunk/include/linux/netfilter_ipv4/ip_tables.h +++ b/trunk/include/linux/netfilter_ipv4/ip_tables.h @@ -25,14 +25,8 @@ #include #include -#include - -#define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN -#define IPT_TABLE_MAXNAMELEN XT_FUNCTION_MAXNAMELEN -#define ipt_match xt_match -#define ipt_target xt_target -#define ipt_table xt_table -#define ipt_get_revision xt_get_revision +#define IPT_FUNCTION_MAXNAMELEN 30 +#define IPT_TABLE_MAXNAMELEN 32 /* Yes, Virginia, you have to zero the padding. */ struct ipt_ip { @@ -108,7 +102,10 @@ struct ipt_standard_target int verdict; }; -#define ipt_counters xt_counters +struct ipt_counters +{ + u_int64_t pcnt, bcnt; /* Packet and byte counters */ +}; /* Values for "flag" field in struct ipt_ip (general ip structure). */ #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ @@ -122,7 +119,7 @@ struct ipt_standard_target #define IPT_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */ #define IPT_INV_DSTIP 0x10 /* Invert the sense of DST OP. */ #define IPT_INV_FRAG 0x20 /* Invert the sense of FRAG. */ -#define IPT_INV_PROTO XT_INV_PROTO +#define IPT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ #define IPT_INV_MASK 0x7F /* All possible flag bits mask. */ /* This structure defines each of the firewall rules. Consists of 3 @@ -144,7 +141,7 @@ struct ipt_entry unsigned int comefrom; /* Packet and byte counters. */ - struct xt_counters counters; + struct ipt_counters counters; /* The matches (if any), then the target. */ unsigned char elems[0]; @@ -154,34 +151,54 @@ struct ipt_entry * New IP firewall options for [gs]etsockopt at the RAW IP level. * Unlike BSD Linux inherits IP options so you don't have to use a raw * socket for this. Instead we check rights in the calls. */ -#define IPT_BASE_CTL XT_BASE_CTL +#define IPT_BASE_CTL 64 /* base for firewall socket options */ -#define IPT_SO_SET_REPLACE XT_SO_SET_REPLACE -#define IPT_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS -#define IPT_SO_SET_MAX XT_SO_SET_MAX +#define IPT_SO_SET_REPLACE (IPT_BASE_CTL) +#define IPT_SO_SET_ADD_COUNTERS (IPT_BASE_CTL + 1) +#define IPT_SO_SET_MAX IPT_SO_SET_ADD_COUNTERS -#define IPT_SO_GET_INFO XT_SO_GET_INFO -#define IPT_SO_GET_ENTRIES XT_SO_GET_ENTRIES -#define IPT_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH -#define IPT_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET -#define IPT_SO_GET_MAX XT_SO_GET_REVISION_TARGET +#define IPT_SO_GET_INFO (IPT_BASE_CTL) +#define IPT_SO_GET_ENTRIES (IPT_BASE_CTL + 1) +#define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2) +#define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) +#define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET -#define IPT_CONTINUE XT_CONTINUE -#define IPT_RETURN XT_RETURN +/* CONTINUE verdict for targets */ +#define IPT_CONTINUE 0xFFFFFFFF -#include -#define ipt_udp xt_udp -#define ipt_tcp xt_tcp +/* For standard target */ +#define IPT_RETURN (-NF_REPEAT - 1) -#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT -#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT -#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS -#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION -#define IPT_TCP_INV_MASK XT_TCP_INV_MASK +/* TCP matching stuff */ +struct ipt_tcp +{ + u_int16_t spts[2]; /* Source port range. */ + u_int16_t dpts[2]; /* Destination port range. */ + u_int8_t option; /* TCP Option iff non-zero*/ + u_int8_t flg_mask; /* TCP flags mask byte */ + u_int8_t flg_cmp; /* TCP flags compare byte */ + u_int8_t invflags; /* Inverse flags */ +}; + +/* Values for "inv" field in struct ipt_tcp. */ +#define IPT_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ +#define IPT_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ +#define IPT_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ +#define IPT_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ +#define IPT_TCP_INV_MASK 0x0F /* All possible flags. */ + +/* UDP matching stuff */ +struct ipt_udp +{ + u_int16_t spts[2]; /* Source port range. */ + u_int16_t dpts[2]; /* Destination port range. */ + u_int8_t invflags; /* Inverse flags */ +}; -#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT -#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT -#define IPT_UDP_INV_MASK XT_UDP_INV_MASK +/* Values for "invflags" field in struct ipt_udp. */ +#define IPT_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ +#define IPT_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ +#define IPT_UDP_INV_MASK 0x03 /* All possible flags. */ /* ICMP matching stuff */ struct ipt_icmp @@ -243,14 +260,23 @@ struct ipt_replace /* Number of counters (must be equal to current number of entries). */ unsigned int num_counters; /* The old entries' counters. */ - struct xt_counters __user *counters; + struct ipt_counters __user *counters; /* The entries (hang off end: not really an array). */ struct ipt_entry entries[0]; }; /* The argument to IPT_SO_ADD_COUNTERS. */ -#define ipt_counters_info xt_counters_info +struct ipt_counters_info +{ + /* Which table. */ + char name[IPT_TABLE_MAXNAMELEN]; + + unsigned int num_counters; + + /* The counters (actually `number' of these). */ + struct ipt_counters counters[0]; +}; /* The argument to IPT_SO_GET_ENTRIES. */ struct ipt_get_entries @@ -265,10 +291,19 @@ struct ipt_get_entries struct ipt_entry entrytable[0]; }; +/* The argument to IPT_SO_GET_REVISION_*. Returns highest revision + * kernel supports, if >= revision. */ +struct ipt_get_revision +{ + char name[IPT_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; +}; + /* Standard return verdict, or do jump. */ -#define IPT_STANDARD_TARGET XT_STANDARD_TARGET +#define IPT_STANDARD_TARGET "" /* Error verdict. */ -#define IPT_ERROR_TARGET XT_ERROR_TARGET +#define IPT_ERROR_TARGET "ERROR" /* Helper functions */ static __inline__ struct ipt_entry_target * @@ -321,18 +356,103 @@ ipt_get_target(struct ipt_entry *e) #include extern void ipt_init(void) __init; -#define ipt_register_target(tgt) xt_register_target(AF_INET, tgt) -#define ipt_unregister_target(tgt) xt_unregister_target(AF_INET, tgt) +struct ipt_match +{ + struct list_head list; + + const char name[IPT_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; + + /* Return true or false: return FALSE and set *hotdrop = 1 to + force immediate packet drop. */ + /* Arguments changed since 2.4, as this must now handle + non-linear skbs, using skb_copy_bits and + skb_ip_make_writable. */ + int (*match)(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop); + + /* Called when user tries to insert an entry of this type. */ + /* Should return true or false. */ + int (*checkentry)(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchinfosize, + unsigned int hook_mask); + + /* Called when entry of this type deleted. */ + void (*destroy)(void *matchinfo, unsigned int matchinfosize); + + /* Set this to THIS_MODULE. */ + struct module *me; +}; -#define ipt_register_match(mtch) xt_register_match(AF_INET, mtch) -#define ipt_unregister_match(mtch) xt_unregister_match(AF_INET, mtch) +/* Registration hooks for targets. */ +struct ipt_target +{ + struct list_head list; + + const char name[IPT_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; + + /* Called when user tries to insert an entry of this type: + hook_mask is a bitmask of hooks from which it can be + called. */ + /* Should return true or false. */ + int (*checkentry)(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask); + + /* Called when entry of this type deleted. */ + void (*destroy)(void *targinfo, unsigned int targinfosize); + + /* Returns verdict. Argument order changed since 2.4, as this + must now handle non-linear skbs, using skb_copy_bits and + skb_ip_make_writable. */ + unsigned int (*target)(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userdata); + + /* Set this to THIS_MODULE. */ + struct module *me; +}; -//#define ipt_register_table(tbl, repl) xt_register_table(AF_INET, tbl, repl) -//#define ipt_unregister_table(tbl) xt_unregister_table(AF_INET, tbl) +extern int ipt_register_target(struct ipt_target *target); +extern void ipt_unregister_target(struct ipt_target *target); -extern int ipt_register_table(struct ipt_table *table, - const struct ipt_replace *repl); -extern void ipt_unregister_table(struct ipt_table *table); +extern int ipt_register_match(struct ipt_match *match); +extern void ipt_unregister_match(struct ipt_match *match); + +/* Furniture shopping... */ +struct ipt_table +{ + struct list_head list; + + /* A unique name... */ + char name[IPT_TABLE_MAXNAMELEN]; + + /* What hooks you will enter on */ + unsigned int valid_hooks; + + /* Lock for the curtain */ + rwlock_t lock; + + /* Man behind the curtain... */ + struct ipt_table_info *private; + + /* Set to THIS_MODULE. */ + struct module *me; +}; /* net/sched/ipt.c: Gimme access to your targets! Gets target->me. */ extern struct ipt_target *ipt_find_target(const char *name, u8 revision); @@ -356,6 +476,9 @@ struct ipt_error struct ipt_error_target target; }; +extern int ipt_register_table(struct ipt_table *table, + const struct ipt_replace *repl); +extern void ipt_unregister_table(struct ipt_table *table); extern unsigned int ipt_do_table(struct sk_buff **pskb, unsigned int hook, const struct net_device *in, @@ -363,6 +486,6 @@ extern unsigned int ipt_do_table(struct sk_buff **pskb, struct ipt_table *table, void *userdata); -#define IPT_ALIGN(s) XT_ALIGN(s) +#define IPT_ALIGN(s) (((s) + (__alignof__(struct ipt_entry)-1)) & ~(__alignof__(struct ipt_entry)-1)) #endif /*__KERNEL__*/ #endif /* _IPTABLES_H */ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_CLASSIFY.h b/trunk/include/linux/netfilter_ipv4/ipt_CLASSIFY.h index a46d511b5c36..7596e3dd00ca 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_CLASSIFY.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_CLASSIFY.h @@ -1,7 +1,8 @@ #ifndef _IPT_CLASSIFY_H #define _IPT_CLASSIFY_H -#include -#define ipt_classify_target_info xt_classify_target_info +struct ipt_classify_target_info { + u_int32_t priority; +}; #endif /*_IPT_CLASSIFY_H */ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_CONNMARK.h b/trunk/include/linux/netfilter_ipv4/ipt_CONNMARK.h index 9ecfee0a9e33..d3c02536fc4c 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_CONNMARK.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_CONNMARK.h @@ -9,11 +9,17 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ -#include -#define IPT_CONNMARK_SET XT_CONNMARK_SET -#define IPT_CONNMARK_SAVE XT_CONNMARK_SAVE -#define IPT_CONNMARK_RESTORE XT_CONNMARK_RESTORE -#define ipt_connmark_target_info xt_connmark_target_info +enum { + IPT_CONNMARK_SET = 0, + IPT_CONNMARK_SAVE, + IPT_CONNMARK_RESTORE +}; + +struct ipt_connmark_target_info { + unsigned long mark; + unsigned long mask; + u_int8_t mode; +}; #endif /*_IPT_CONNMARK_H_target*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_MARK.h b/trunk/include/linux/netfilter_ipv4/ipt_MARK.h index 697a486a96d3..f47485790ed4 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_MARK.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_MARK.h @@ -1,18 +1,20 @@ #ifndef _IPT_MARK_H_target #define _IPT_MARK_H_target -/* Backwards compatibility for old userspace */ - -#include - /* Version 0 */ -#define ipt_mark_target_info xt_mark_target_info +struct ipt_mark_target_info { + unsigned long mark; +}; /* Version 1 */ -#define IPT_MARK_SET XT_MARK_SET -#define IPT_MARK_AND XT_MARK_AND -#define IPT_MARK_OR XT_MARK_OR - -#define ipt_mark_target_info_v1 xt_mark_target_info_v1 +enum { + IPT_MARK_SET=0, + IPT_MARK_AND, + IPT_MARK_OR +}; +struct ipt_mark_target_info_v1 { + unsigned long mark; + u_int8_t mode; +}; #endif /*_IPT_MARK_H_target*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_NFQUEUE.h b/trunk/include/linux/netfilter_ipv4/ipt_NFQUEUE.h index 97a2a7557cb9..b5b2943b0c66 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_NFQUEUE.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_NFQUEUE.h @@ -8,9 +8,9 @@ #ifndef _IPT_NFQ_TARGET_H #define _IPT_NFQ_TARGET_H -/* Backwards compatibility for old userspace */ -#include - -#define ipt_NFQ_info xt_NFQ_info +/* target info */ +struct ipt_NFQ_info { + u_int16_t queuenum; +}; #endif /* _IPT_DSCP_TARGET_H */ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_comment.h b/trunk/include/linux/netfilter_ipv4/ipt_comment.h index ae2afc2f7481..85c1123c29ce 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_comment.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_comment.h @@ -1,10 +1,10 @@ #ifndef _IPT_COMMENT_H #define _IPT_COMMENT_H -#include +#define IPT_MAX_COMMENT_LEN 256 -#define IPT_MAX_COMMENT_LEN XT_MAX_COMMENT_LEN - -#define ipt_comment_info xt_comment_info +struct ipt_comment_info { + unsigned char comment[IPT_MAX_COMMENT_LEN]; +}; #endif /* _IPT_COMMENT_H */ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_connbytes.h b/trunk/include/linux/netfilter_ipv4/ipt_connbytes.h index b04dfa3083c9..9e5532f8d8ac 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_connbytes.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_connbytes.h @@ -1,18 +1,25 @@ #ifndef _IPT_CONNBYTES_H #define _IPT_CONNBYTES_H -#include -#define ipt_connbytes_what xt_connbytes_what +enum ipt_connbytes_what { + IPT_CONNBYTES_PKTS, + IPT_CONNBYTES_BYTES, + IPT_CONNBYTES_AVGPKT, +}; -#define IPT_CONNBYTES_PKTS XT_CONNBYTES_PACKETS -#define IPT_CONNBYTES_BYTES XT_CONNBYTES_BYTES -#define IPT_CONNBYTES_AVGPKT XT_CONNBYTES_AVGPKT - -#define ipt_connbytes_direction xt_connbytes_direction -#define IPT_CONNBYTES_DIR_ORIGINAL XT_CONNBYTES_DIR_ORIGINAL -#define IPT_CONNBYTES_DIR_REPLY XT_CONNBYTES_DIR_REPLY -#define IPT_CONNBYTES_DIR_BOTH XT_CONNBYTES_DIR_BOTH - -#define ipt_connbytes_info xt_connbytes_info +enum ipt_connbytes_direction { + IPT_CONNBYTES_DIR_ORIGINAL, + IPT_CONNBYTES_DIR_REPLY, + IPT_CONNBYTES_DIR_BOTH, +}; +struct ipt_connbytes_info +{ + struct { + aligned_u64 from; /* count to be matched */ + aligned_u64 to; /* count to be matched */ + } count; + u_int8_t what; /* ipt_connbytes_what */ + u_int8_t direction; /* ipt_connbytes_direction */ +}; #endif diff --git a/trunk/include/linux/netfilter_ipv4/ipt_connmark.h b/trunk/include/linux/netfilter_ipv4/ipt_connmark.h index c7ba6560d44c..46573270d9aa 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_connmark.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_connmark.h @@ -1,7 +1,18 @@ #ifndef _IPT_CONNMARK_H #define _IPT_CONNMARK_H -#include -#define ipt_connmark_info xt_connmark_info +/* Copyright (C) 2002,2004 MARA Systems AB + * by Henrik Nordstrom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +struct ipt_connmark_info { + unsigned long mark, mask; + u_int8_t invert; +}; #endif /*_IPT_CONNMARK_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_conntrack.h b/trunk/include/linux/netfilter_ipv4/ipt_conntrack.h index cde6762949c5..413c5658bd3a 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_conntrack.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_conntrack.h @@ -5,24 +5,56 @@ #ifndef _IPT_CONNTRACK_H #define _IPT_CONNTRACK_H -#include +#define IPT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) +#define IPT_CONNTRACK_STATE_INVALID (1 << 0) -#define IPT_CONNTRACK_STATE_BIT(ctinfo) XT_CONNTRACK_STATE_BIT(ctinfo) -#define IPT_CONNTRACK_STATE_INVALID XT_CONNTRACK_STATE_INVALID - -#define IPT_CONNTRACK_STATE_SNAT XT_CONNTRACK_STATE_SNAT -#define IPT_CONNTRACK_STATE_DNAT XT_CONNTRACK_STATE_DNAT -#define IPT_CONNTRACK_STATE_UNTRACKED XT_CONNTRACK_STATE_UNTRACKED +#define IPT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1)) +#define IPT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2)) +#define IPT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) /* flags, invflags: */ -#define IPT_CONNTRACK_STATE XT_CONNTRACK_STATE -#define IPT_CONNTRACK_PROTO XT_CONNTRACK_PROTO -#define IPT_CONNTRACK_ORIGSRC XT_CONNTRACK_ORIGSRC -#define IPT_CONNTRACK_ORIGDST XT_CONNTRACK_ORIGDST -#define IPT_CONNTRACK_REPLSRC XT_CONNTRACK_REPLSRC -#define IPT_CONNTRACK_REPLDST XT_CONNTRACK_REPLDST -#define IPT_CONNTRACK_STATUS XT_CONNTRACK_STATUS -#define IPT_CONNTRACK_EXPIRES XT_CONNTRACK_EXPIRES - -#define ipt_conntrack_info xt_conntrack_info +#define IPT_CONNTRACK_STATE 0x01 +#define IPT_CONNTRACK_PROTO 0x02 +#define IPT_CONNTRACK_ORIGSRC 0x04 +#define IPT_CONNTRACK_ORIGDST 0x08 +#define IPT_CONNTRACK_REPLSRC 0x10 +#define IPT_CONNTRACK_REPLDST 0x20 +#define IPT_CONNTRACK_STATUS 0x40 +#define IPT_CONNTRACK_EXPIRES 0x80 + +/* This is exposed to userspace, so remains frozen in time. */ +struct ip_conntrack_old_tuple +{ + struct { + __u32 ip; + union { + __u16 all; + } u; + } src; + + struct { + __u32 ip; + union { + __u16 all; + } u; + + /* The protocol. */ + u16 protonum; + } dst; +}; + +struct ipt_conntrack_info +{ + unsigned int statemask, statusmask; + + struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX]; + struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX]; + + unsigned long expires_min, expires_max; + + /* Flags word */ + u_int8_t flags; + /* Inverse flags */ + u_int8_t invflags; +}; #endif /*_IPT_CONNTRACK_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_dccp.h b/trunk/include/linux/netfilter_ipv4/ipt_dccp.h index e70d11e1f53c..3cb3a522e62b 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_dccp.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_dccp.h @@ -1,15 +1,23 @@ #ifndef _IPT_DCCP_H_ #define _IPT_DCCP_H_ -#include -#define IPT_DCCP_SRC_PORTS XT_DCCP_SRC_PORTS -#define IPT_DCCP_DEST_PORTS XT_DCCP_DEST_PORTS -#define IPT_DCCP_TYPE XT_DCCP_TYPE -#define IPT_DCCP_OPTION XT_DCCP_OPTION +#define IPT_DCCP_SRC_PORTS 0x01 +#define IPT_DCCP_DEST_PORTS 0x02 +#define IPT_DCCP_TYPE 0x04 +#define IPT_DCCP_OPTION 0x08 -#define IPT_DCCP_VALID_FLAGS XT_DCCP_VALID_FLAGS +#define IPT_DCCP_VALID_FLAGS 0x0f -#define ipt_dccp_info xt_dccp_info +struct ipt_dccp_info { + u_int16_t dpts[2]; /* Min, Max */ + u_int16_t spts[2]; /* Min, Max */ + + u_int16_t flags; + u_int16_t invflags; + + u_int16_t typemask; + u_int8_t option; +}; #endif /* _IPT_DCCP_H_ */ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_helper.h b/trunk/include/linux/netfilter_ipv4/ipt_helper.h index 80452c218551..6f12ecb8c93d 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_helper.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_helper.h @@ -1,7 +1,8 @@ #ifndef _IPT_HELPER_H #define _IPT_HELPER_H -#include -#define ipt_helper_info xt_helper_info - +struct ipt_helper_info { + int invert; + char name[30]; +}; #endif /* _IPT_HELPER_H */ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_length.h b/trunk/include/linux/netfilter_ipv4/ipt_length.h index 9b45206ffcef..6e0885229615 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_length.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_length.h @@ -1,7 +1,9 @@ #ifndef _IPT_LENGTH_H #define _IPT_LENGTH_H -#include -#define ipt_length_info xt_length_info +struct ipt_length_info { + u_int16_t min, max; + u_int8_t invert; +}; #endif /*_IPT_LENGTH_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_limit.h b/trunk/include/linux/netfilter_ipv4/ipt_limit.h index 92f5cd07bbc4..256453409e21 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_limit.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_limit.h @@ -1,8 +1,21 @@ #ifndef _IPT_RATE_H #define _IPT_RATE_H -#include -#define IPT_LIMIT_SCALE XT_LIMIT_SCALE -#define ipt_rateinfo xt_rateinfo +/* timings are in milliseconds. */ +#define IPT_LIMIT_SCALE 10000 +/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 + seconds, or one every 59 hours. */ +struct ipt_rateinfo { + u_int32_t avg; /* Average secs between packets * scale */ + u_int32_t burst; /* Period multiplier for upper limit. */ + + /* Used internally by the kernel */ + unsigned long prev; + u_int32_t credit; + u_int32_t credit_cap, cost; + + /* Ugly, ugly fucker. */ + struct ipt_rateinfo *master; +}; #endif /*_IPT_RATE_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_mac.h b/trunk/include/linux/netfilter_ipv4/ipt_mac.h index b186008a3c47..f8d5b8e7ccdb 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_mac.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_mac.h @@ -1,7 +1,8 @@ #ifndef _IPT_MAC_H #define _IPT_MAC_H -#include -#define ipt_mac_info xt_mac_info - +struct ipt_mac_info { + unsigned char srcaddr[ETH_ALEN]; + int invert; +}; #endif /*_IPT_MAC_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_mark.h b/trunk/include/linux/netfilter_ipv4/ipt_mark.h index bfde67c61224..f3952b563d4c 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_mark.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_mark.h @@ -1,9 +1,9 @@ #ifndef _IPT_MARK_H #define _IPT_MARK_H -/* Backwards compatibility for old userspace */ -#include - -#define ipt_mark_info xt_mark_info +struct ipt_mark_info { + unsigned long mark, mask; + u_int8_t invert; +}; #endif /*_IPT_MARK_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_physdev.h b/trunk/include/linux/netfilter_ipv4/ipt_physdev.h index 2400e7140f26..7538c8655ec0 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_physdev.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_physdev.h @@ -1,17 +1,24 @@ #ifndef _IPT_PHYSDEV_H #define _IPT_PHYSDEV_H -/* Backwards compatibility for old userspace */ +#ifdef __KERNEL__ +#include +#endif -#include +#define IPT_PHYSDEV_OP_IN 0x01 +#define IPT_PHYSDEV_OP_OUT 0x02 +#define IPT_PHYSDEV_OP_BRIDGED 0x04 +#define IPT_PHYSDEV_OP_ISIN 0x08 +#define IPT_PHYSDEV_OP_ISOUT 0x10 +#define IPT_PHYSDEV_OP_MASK (0x20 - 1) -#define IPT_PHYSDEV_OP_IN XT_PHYSDEV_OP_IN -#define IPT_PHYSDEV_OP_OUT XT_PHYSDEV_OP_OUT -#define IPT_PHYSDEV_OP_BRIDGED XT_PHYSDEV_OP_BRIDGED -#define IPT_PHYSDEV_OP_ISIN XT_PHYSDEV_OP_ISIN -#define IPT_PHYSDEV_OP_ISOUT XT_PHYSDEV_OP_ISOUT -#define IPT_PHYSDEV_OP_MASK XT_PHYSDEV_OP_MASK - -#define ipt_physdev_info xt_physdev_info +struct ipt_physdev_info { + char physindev[IFNAMSIZ]; + char in_mask[IFNAMSIZ]; + char physoutdev[IFNAMSIZ]; + char out_mask[IFNAMSIZ]; + u_int8_t invert; + u_int8_t bitmask; +}; #endif /*_IPT_PHYSDEV_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_pkttype.h b/trunk/include/linux/netfilter_ipv4/ipt_pkttype.h index ff1fbc949a0c..d53a65848683 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_pkttype.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_pkttype.h @@ -1,7 +1,8 @@ #ifndef _IPT_PKTTYPE_H #define _IPT_PKTTYPE_H -#include -#define ipt_pkttype_info xt_pkttype_info - +struct ipt_pkttype_info { + int pkttype; + int invert; +}; #endif /*_IPT_PKTTYPE_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_realm.h b/trunk/include/linux/netfilter_ipv4/ipt_realm.h index b3996eaa0188..a4d6698723ac 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_realm.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_realm.h @@ -1,7 +1,10 @@ #ifndef _IPT_REALM_H #define _IPT_REALM_H -#include -#define ipt_realm_info xt_realm_info +struct ipt_realm_info { + u_int32_t id; + u_int32_t mask; + u_int8_t invert; +}; #endif /* _IPT_REALM_H */ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_state.h b/trunk/include/linux/netfilter_ipv4/ipt_state.h index a44a99cc28cc..5df37868933d 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_state.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_state.h @@ -1,15 +1,13 @@ #ifndef _IPT_STATE_H #define _IPT_STATE_H -/* Backwards compatibility for old userspace */ +#define IPT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) +#define IPT_STATE_INVALID (1 << 0) -#include - -#define IPT_STATE_BIT XT_STATE_BIT -#define IPT_STATE_INVALID XT_STATE_INVALID - -#define IPT_STATE_UNTRACKED XT_STATE_UNTRACKED - -#define ipt_state_info xt_state_info +#define IPT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1)) +struct ipt_state_info +{ + unsigned int statemask; +}; #endif /*_IPT_STATE_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_string.h b/trunk/include/linux/netfilter_ipv4/ipt_string.h index c26de3059903..a265f6e44eab 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_string.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_string.h @@ -1,10 +1,18 @@ #ifndef _IPT_STRING_H #define _IPT_STRING_H -#include +#define IPT_STRING_MAX_PATTERN_SIZE 128 +#define IPT_STRING_MAX_ALGO_NAME_SIZE 16 -#define IPT_STRING_MAX_PATTERN_SIZE XT_STRING_MAX_PATTERN_SIZE -#define IPT_STRING_MAX_ALGO_NAME_SIZE XT_STRING_MAX_ALGO_NAME_SIZE -#define ipt_string_info xt_string_info +struct ipt_string_info +{ + u_int16_t from_offset; + u_int16_t to_offset; + char algo[IPT_STRING_MAX_ALGO_NAME_SIZE]; + char pattern[IPT_STRING_MAX_PATTERN_SIZE]; + u_int8_t patlen; + u_int8_t invert; + struct ts_config __attribute__((aligned(8))) *config; +}; #endif /*_IPT_STRING_H*/ diff --git a/trunk/include/linux/netfilter_ipv4/ipt_tcpmss.h b/trunk/include/linux/netfilter_ipv4/ipt_tcpmss.h index 18bbc8e8e009..e2b14397f701 100644 --- a/trunk/include/linux/netfilter_ipv4/ipt_tcpmss.h +++ b/trunk/include/linux/netfilter_ipv4/ipt_tcpmss.h @@ -1,7 +1,9 @@ #ifndef _IPT_TCPMSS_MATCH_H #define _IPT_TCPMSS_MATCH_H -#include -#define ipt_tcpmss_match_info xt_tcpmss_match_info +struct ipt_tcpmss_match_info { + u_int16_t mss_min, mss_max; + u_int8_t invert; +}; #endif /*_IPT_TCPMSS_MATCH_H*/ diff --git a/trunk/include/linux/netfilter_ipv6/ip6_tables.h b/trunk/include/linux/netfilter_ipv6/ip6_tables.h index f249b574f0fa..c163ba31aab7 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6_tables.h +++ b/trunk/include/linux/netfilter_ipv6/ip6_tables.h @@ -25,15 +25,8 @@ #include #include -#include - -#define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN -#define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN - -#define ip6t_match xt_match -#define ip6t_target xt_target -#define ip6t_table xt_table -#define ip6t_get_revision xt_get_revision +#define IP6T_FUNCTION_MAXNAMELEN 30 +#define IP6T_TABLE_MAXNAMELEN 32 /* Yes, Virginia, you have to zero the padding. */ struct ip6t_ip6 { @@ -111,7 +104,10 @@ struct ip6t_standard_target int verdict; }; -#define ip6t_counters xt_counters +struct ip6t_counters +{ + u_int64_t pcnt, bcnt; /* Packet and byte counters */ +}; /* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */ #define IP6T_F_PROTO 0x01 /* Set if rule cares about upper @@ -127,7 +123,7 @@ struct ip6t_standard_target #define IP6T_INV_SRCIP 0x08 /* Invert the sense of SRC IP. */ #define IP6T_INV_DSTIP 0x10 /* Invert the sense of DST OP. */ #define IP6T_INV_FRAG 0x20 /* Invert the sense of FRAG. */ -#define IP6T_INV_PROTO XT_INV_PROTO +#define IP6T_INV_PROTO 0x40 /* Invert the sense of PROTO. */ #define IP6T_INV_MASK 0x7F /* All possible flag bits mask. */ /* This structure defines each of the firewall rules. Consists of 3 @@ -149,7 +145,7 @@ struct ip6t_entry unsigned int comefrom; /* Packet and byte counters. */ - struct xt_counters counters; + struct ip6t_counters counters; /* The matches (if any), then the target. */ unsigned char elems[0]; @@ -159,41 +155,54 @@ struct ip6t_entry * New IP firewall options for [gs]etsockopt at the RAW IP level. * Unlike BSD Linux inherits IP options so you don't have to use * a raw socket for this. Instead we check rights in the calls. */ -#define IP6T_BASE_CTL XT_BASE_CTL +#define IP6T_BASE_CTL 64 /* base for firewall socket options */ -#define IP6T_SO_SET_REPLACE XT_SO_SET_REPLACE -#define IP6T_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS -#define IP6T_SO_SET_MAX XT_SO_SET_MAX +#define IP6T_SO_SET_REPLACE (IP6T_BASE_CTL) +#define IP6T_SO_SET_ADD_COUNTERS (IP6T_BASE_CTL + 1) +#define IP6T_SO_SET_MAX IP6T_SO_SET_ADD_COUNTERS -#define IP6T_SO_GET_INFO XT_SO_GET_INFO -#define IP6T_SO_GET_ENTRIES XT_SO_GET_ENTRIES -#define IP6T_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH -#define IP6T_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET -#define IP6T_SO_GET_MAX XT_SO_GET_REVISION_TARGET +#define IP6T_SO_GET_INFO (IP6T_BASE_CTL) +#define IP6T_SO_GET_ENTRIES (IP6T_BASE_CTL + 1) +#define IP6T_SO_GET_REVISION_MATCH (IP6T_BASE_CTL + 2) +#define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 3) +#define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET /* CONTINUE verdict for targets */ -#define IP6T_CONTINUE XT_CONTINUE +#define IP6T_CONTINUE 0xFFFFFFFF /* For standard target */ -#define IP6T_RETURN XT_RETURN - -/* TCP/UDP matching stuff */ -#include +#define IP6T_RETURN (-NF_REPEAT - 1) -#define ip6t_tcp xt_tcp -#define ip6t_udp xt_udp +/* TCP matching stuff */ +struct ip6t_tcp +{ + u_int16_t spts[2]; /* Source port range. */ + u_int16_t dpts[2]; /* Destination port range. */ + u_int8_t option; /* TCP Option iff non-zero*/ + u_int8_t flg_mask; /* TCP flags mask byte */ + u_int8_t flg_cmp; /* TCP flags compare byte */ + u_int8_t invflags; /* Inverse flags */ +}; /* Values for "inv" field in struct ipt_tcp. */ -#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT -#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT -#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS -#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION -#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK +#define IP6T_TCP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ +#define IP6T_TCP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ +#define IP6T_TCP_INV_FLAGS 0x04 /* Invert the sense of TCP flags. */ +#define IP6T_TCP_INV_OPTION 0x08 /* Invert the sense of option test. */ +#define IP6T_TCP_INV_MASK 0x0F /* All possible flags. */ + +/* UDP matching stuff */ +struct ip6t_udp +{ + u_int16_t spts[2]; /* Source port range. */ + u_int16_t dpts[2]; /* Destination port range. */ + u_int8_t invflags; /* Inverse flags */ +}; /* Values for "invflags" field in struct ipt_udp. */ -#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT -#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT -#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK +#define IP6T_UDP_INV_SRCPT 0x01 /* Invert the sense of source ports. */ +#define IP6T_UDP_INV_DSTPT 0x02 /* Invert the sense of dest ports. */ +#define IP6T_UDP_INV_MASK 0x03 /* All possible flags. */ /* ICMP matching stuff */ struct ip6t_icmp @@ -255,14 +264,23 @@ struct ip6t_replace /* Number of counters (must be equal to current number of entries). */ unsigned int num_counters; /* The old entries' counters. */ - struct xt_counters __user *counters; + struct ip6t_counters __user *counters; /* The entries (hang off end: not really an array). */ struct ip6t_entry entries[0]; }; /* The argument to IP6T_SO_ADD_COUNTERS. */ -#define ip6t_counters_info xt_counters_info +struct ip6t_counters_info +{ + /* Which table. */ + char name[IP6T_TABLE_MAXNAMELEN]; + + unsigned int num_counters; + + /* The counters (actually `number' of these). */ + struct ip6t_counters counters[0]; +}; /* The argument to IP6T_SO_GET_ENTRIES. */ struct ip6t_get_entries @@ -277,10 +295,19 @@ struct ip6t_get_entries struct ip6t_entry entrytable[0]; }; +/* The argument to IP6T_SO_GET_REVISION_*. Returns highest revision + * kernel supports, if >= revision. */ +struct ip6t_get_revision +{ + char name[IP6T_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; +}; + /* Standard return verdict, or do jump. */ -#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET +#define IP6T_STANDARD_TARGET "" /* Error verdict. */ -#define IP6T_ERROR_TARGET XT_ERROR_TARGET +#define IP6T_ERROR_TARGET "ERROR" /* Helper functions */ static __inline__ struct ip6t_entry_target * @@ -334,11 +361,104 @@ ip6t_get_target(struct ip6t_entry *e) #include extern void ip6t_init(void) __init; -#define ip6t_register_target(tgt) xt_register_target(AF_INET6, tgt) -#define ip6t_unregister_target(tgt) xt_unregister_target(AF_INET6, tgt) +struct ip6t_match +{ + struct list_head list; + + const char name[IP6T_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; + + /* Return true or false: return FALSE and set *hotdrop = 1 to + force immediate packet drop. */ + /* Arguments changed since 2.6.9, as this must now handle + non-linear skb, using skb_header_pointer and + skb_ip_make_writable. */ + int (*match)(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop); + + /* Called when user tries to insert an entry of this type. */ + /* Should return true or false. */ + int (*checkentry)(const char *tablename, + const struct ip6t_ip6 *ip, + void *matchinfo, + unsigned int matchinfosize, + unsigned int hook_mask); + + /* Called when entry of this type deleted. */ + void (*destroy)(void *matchinfo, unsigned int matchinfosize); + + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ + struct module *me; +}; + +/* Registration hooks for targets. */ +struct ip6t_target +{ + struct list_head list; + + const char name[IP6T_FUNCTION_MAXNAMELEN-1]; + + u_int8_t revision; + + /* Returns verdict. Argument order changed since 2.6.9, as this + must now handle non-linear skbs, using skb_copy_bits and + skb_ip_make_writable. */ + unsigned int (*target)(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userdata); + + /* Called when user tries to insert an entry of this type: + hook_mask is a bitmask of hooks from which it can be + called. */ + /* Should return true or false. */ + int (*checkentry)(const char *tablename, + const struct ip6t_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask); + + /* Called when entry of this type deleted. */ + void (*destroy)(void *targinfo, unsigned int targinfosize); + + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ + struct module *me; +}; + +extern int ip6t_register_target(struct ip6t_target *target); +extern void ip6t_unregister_target(struct ip6t_target *target); + +extern int ip6t_register_match(struct ip6t_match *match); +extern void ip6t_unregister_match(struct ip6t_match *match); -#define ip6t_register_match(match) xt_register_match(AF_INET6, match) -#define ip6t_unregister_match(match) xt_unregister_match(AF_INET6, match) +/* Furniture shopping... */ +struct ip6t_table +{ + struct list_head list; + + /* A unique name... */ + char name[IP6T_TABLE_MAXNAMELEN]; + + /* What hooks you will enter on */ + unsigned int valid_hooks; + + /* Lock for the curtain */ + rwlock_t lock; + + /* Man behind the curtain... */ + struct ip6t_table_info *private; + + /* Set this to THIS_MODULE if you are a module, otherwise NULL */ + struct module *me; +}; extern int ip6t_register_table(struct ip6t_table *table, const struct ip6t_replace *repl); diff --git a/trunk/include/linux/netfilter_ipv6/ip6t_MARK.h b/trunk/include/linux/netfilter_ipv6/ip6t_MARK.h index 7cf629a8ab92..7ade8d8f5246 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6t_MARK.h +++ b/trunk/include/linux/netfilter_ipv6/ip6t_MARK.h @@ -1,9 +1,8 @@ #ifndef _IP6T_MARK_H_target #define _IP6T_MARK_H_target -/* Backwards compatibility for old userspace */ -#include +struct ip6t_mark_target_info { + unsigned long mark; +}; -#define ip6t_mark_target_info xt_mark_target_info - -#endif /*_IP6T_MARK_H_target*/ +#endif /*_IPT_MARK_H_target*/ diff --git a/trunk/include/linux/netfilter_ipv6/ip6t_length.h b/trunk/include/linux/netfilter_ipv6/ip6t_length.h index 9e9689d03ed7..7fc09f9f9d63 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6t_length.h +++ b/trunk/include/linux/netfilter_ipv6/ip6t_length.h @@ -1,8 +1,10 @@ #ifndef _IP6T_LENGTH_H #define _IP6T_LENGTH_H -#include -#define ip6t_length_info xt_length_info +struct ip6t_length_info { + u_int16_t min, max; + u_int8_t invert; +}; #endif /*_IP6T_LENGTH_H*/ diff --git a/trunk/include/linux/netfilter_ipv6/ip6t_limit.h b/trunk/include/linux/netfilter_ipv6/ip6t_limit.h index 487e5ea342c6..f2866e50f3b4 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6t_limit.h +++ b/trunk/include/linux/netfilter_ipv6/ip6t_limit.h @@ -1,8 +1,21 @@ #ifndef _IP6T_RATE_H #define _IP6T_RATE_H -#include -#define IP6T_LIMIT_SCALE XT_LIMIT_SCALE -#define ip6t_rateinfo xt_rateinfo +/* timings are in milliseconds. */ +#define IP6T_LIMIT_SCALE 10000 -#endif /*_IP6T_RATE_H*/ +/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 + seconds, or one every 59 hours. */ +struct ip6t_rateinfo { + u_int32_t avg; /* Average secs between packets * scale */ + u_int32_t burst; /* Period multiplier for upper limit. */ + + /* Used internally by the kernel */ + unsigned long prev; + u_int32_t credit; + u_int32_t credit_cap, cost; + + /* Ugly, ugly fucker. */ + struct ip6t_rateinfo *master; +}; +#endif /*_IPT_RATE_H*/ diff --git a/trunk/include/linux/netfilter_ipv6/ip6t_mac.h b/trunk/include/linux/netfilter_ipv6/ip6t_mac.h index ac58e83e9423..87c088c21848 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6t_mac.h +++ b/trunk/include/linux/netfilter_ipv6/ip6t_mac.h @@ -1,7 +1,8 @@ #ifndef _IP6T_MAC_H #define _IP6T_MAC_H -#include -#define ip6t_mac_info xt_mac_info - -#endif /*_IP6T_MAC_H*/ +struct ip6t_mac_info { + unsigned char srcaddr[ETH_ALEN]; + int invert; +}; +#endif /*_IPT_MAC_H*/ diff --git a/trunk/include/linux/netfilter_ipv6/ip6t_mark.h b/trunk/include/linux/netfilter_ipv6/ip6t_mark.h index ff204951ddc3..a734441e1c19 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6t_mark.h +++ b/trunk/include/linux/netfilter_ipv6/ip6t_mark.h @@ -1,9 +1,9 @@ #ifndef _IP6T_MARK_H #define _IP6T_MARK_H -/* Backwards compatibility for old userspace */ -#include - -#define ip6t_mark_info xt_mark_info +struct ip6t_mark_info { + unsigned long mark, mask; + u_int8_t invert; +}; #endif /*_IPT_MARK_H*/ diff --git a/trunk/include/linux/netfilter_ipv6/ip6t_physdev.h b/trunk/include/linux/netfilter_ipv6/ip6t_physdev.h index c161c0a81b55..c234731cd66b 100644 --- a/trunk/include/linux/netfilter_ipv6/ip6t_physdev.h +++ b/trunk/include/linux/netfilter_ipv6/ip6t_physdev.h @@ -1,17 +1,24 @@ #ifndef _IP6T_PHYSDEV_H #define _IP6T_PHYSDEV_H -/* Backwards compatibility for old userspace */ +#ifdef __KERNEL__ +#include +#endif -#include +#define IP6T_PHYSDEV_OP_IN 0x01 +#define IP6T_PHYSDEV_OP_OUT 0x02 +#define IP6T_PHYSDEV_OP_BRIDGED 0x04 +#define IP6T_PHYSDEV_OP_ISIN 0x08 +#define IP6T_PHYSDEV_OP_ISOUT 0x10 +#define IP6T_PHYSDEV_OP_MASK (0x20 - 1) -#define IP6T_PHYSDEV_OP_IN XT_PHYSDEV_OP_IN -#define IP6T_PHYSDEV_OP_OUT XT_PHYSDEV_OP_OUT -#define IP6T_PHYSDEV_OP_BRIDGED XT_PHYSDEV_OP_BRIDGED -#define IP6T_PHYSDEV_OP_ISIN XT_PHYSDEV_OP_ISIN -#define IP6T_PHYSDEV_OP_ISOUT XT_PHYSDEV_OP_ISOUT -#define IP6T_PHYSDEV_OP_MASK XT_PHYSDEV_OP_MASK - -#define ip6t_physdev_info xt_physdev_info +struct ip6t_physdev_info { + char physindev[IFNAMSIZ]; + char in_mask[IFNAMSIZ]; + char physoutdev[IFNAMSIZ]; + char out_mask[IFNAMSIZ]; + u_int8_t invert; + u_int8_t bitmask; +}; #endif /*_IP6T_PHYSDEV_H*/ diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index aa6322d45198..74488e49166d 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -146,11 +146,6 @@ struct property; extern void proc_device_tree_init(void); extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop); -extern void proc_device_tree_remove_prop(struct proc_dir_entry *pde, - struct property *prop); -extern void proc_device_tree_update_prop(struct proc_dir_entry *pde, - struct property *newprop, - struct property *oldprop); #endif /* CONFIG_PROC_DEVICETREE */ extern struct proc_dir_entry *proc_symlink(const char *, diff --git a/trunk/include/linux/socket.h b/trunk/include/linux/socket.h index b02dda4ee83d..9f4019156fd8 100644 --- a/trunk/include/linux/socket.h +++ b/trunk/include/linux/socket.h @@ -186,7 +186,6 @@ struct ucred { #define AF_PPPOX 24 /* PPPoX sockets */ #define AF_WANPIPE 25 /* Wanpipe API Sockets */ #define AF_LLC 26 /* Linux LLC */ -#define AF_TIPC 30 /* TIPC sockets */ #define AF_BLUETOOTH 31 /* Bluetooth sockets */ #define AF_MAX 32 /* For now.. */ @@ -219,7 +218,6 @@ struct ucred { #define PF_PPPOX AF_PPPOX #define PF_WANPIPE AF_WANPIPE #define PF_LLC AF_LLC -#define PF_TIPC AF_TIPC #define PF_BLUETOOTH AF_BLUETOOTH #define PF_MAX AF_MAX @@ -281,7 +279,6 @@ struct ucred { #define SOL_LLC 268 #define SOL_DCCP 269 #define SOL_NETLINK 270 -#define SOL_TIPC 271 /* IPX options */ #define IPX_TYPE 1 diff --git a/trunk/include/linux/tipc.h b/trunk/include/linux/tipc.h deleted file mode 100644 index 243a15f54002..000000000000 --- a/trunk/include/linux/tipc.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * include/linux/tipc.h: Include file for TIPC socket interface - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _LINUX_TIPC_H_ -#define _LINUX_TIPC_H_ - -#include - -/* - * TIPC addressing primitives - */ - -struct tipc_portid { - __u32 ref; - __u32 node; -}; - -struct tipc_name { - __u32 type; - __u32 instance; -}; - -struct tipc_name_seq { - __u32 type; - __u32 lower; - __u32 upper; -}; - -static inline __u32 tipc_addr(unsigned int zone, - unsigned int cluster, - unsigned int node) -{ - return (zone << 24) | (cluster << 12) | node; -} - -static inline unsigned int tipc_zone(__u32 addr) -{ - return addr >> 24; -} - -static inline unsigned int tipc_cluster(__u32 addr) -{ - return (addr >> 12) & 0xfff; -} - -static inline unsigned int tipc_node(__u32 addr) -{ - return addr & 0xfff; -} - -/* - * Application-accessible port name types - */ - -#define TIPC_CFG_SRV 0 /* configuration service name type */ -#define TIPC_TOP_SRV 1 /* topology service name type */ -#define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */ - -/* - * Publication scopes when binding port names and port name sequences - */ - -#define TIPC_ZONE_SCOPE 1 -#define TIPC_CLUSTER_SCOPE 2 -#define TIPC_NODE_SCOPE 3 - -/* - * Limiting values for messages - */ - -#define TIPC_MAX_USER_MSG_SIZE 66000 - -/* - * Message importance levels - */ - -#define TIPC_LOW_IMPORTANCE 0 /* default */ -#define TIPC_MEDIUM_IMPORTANCE 1 -#define TIPC_HIGH_IMPORTANCE 2 -#define TIPC_CRITICAL_IMPORTANCE 3 - -/* - * Msg rejection/connection shutdown reasons - */ - -#define TIPC_OK 0 -#define TIPC_ERR_NO_NAME 1 -#define TIPC_ERR_NO_PORT 2 -#define TIPC_ERR_NO_NODE 3 -#define TIPC_ERR_OVERLOAD 4 -#define TIPC_CONN_SHUTDOWN 5 - -/* - * TIPC topology subscription service definitions - */ - -#define TIPC_SUB_PORTS 0x01 /* filter for port availability */ -#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ -#if 0 -/* The following filter options are not currently implemented */ -#define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */ -#define TIPC_SUB_NO_UNBIND_EVTS 0x08 /* filter out "withdraw" events */ -#define TIPC_SUB_SINGLE_EVT 0x10 /* expire after first event */ -#endif - -#define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */ - -struct tipc_subscr { - struct tipc_name_seq seq; /* name sequence of interest */ - __u32 timeout; /* subscription duration (in ms) */ - __u32 filter; /* bitmask of filter options */ - char usr_handle[8]; /* available for subscriber use */ -}; - -#define TIPC_PUBLISHED 1 /* publication event */ -#define TIPC_WITHDRAWN 2 /* withdraw event */ -#define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */ - -struct tipc_event { - __u32 event; /* event type */ - __u32 found_lower; /* matching name seq instances */ - __u32 found_upper; /* " " " " */ - struct tipc_portid port; /* associated port */ - struct tipc_subscr s; /* associated subscription */ -}; - -/* - * Socket API - */ - -#ifndef AF_TIPC -#define AF_TIPC 30 -#endif - -#ifndef PF_TIPC -#define PF_TIPC AF_TIPC -#endif - -#ifndef SOL_TIPC -#define SOL_TIPC 271 -#endif - -#define TIPC_ADDR_NAMESEQ 1 -#define TIPC_ADDR_MCAST 1 -#define TIPC_ADDR_NAME 2 -#define TIPC_ADDR_ID 3 - -struct sockaddr_tipc { - unsigned short family; - unsigned char addrtype; - signed char scope; - union { - struct tipc_portid id; - struct tipc_name_seq nameseq; - struct { - struct tipc_name name; - __u32 domain; /* 0: own zone */ - } name; - } addr; -}; - -/* - * Ancillary data objects supported by recvmsg() - */ - -#define TIPC_ERRINFO 1 /* error info */ -#define TIPC_RETDATA 2 /* returned data */ -#define TIPC_DESTNAME 3 /* destination name */ - -/* - * TIPC-specific socket option values - */ - -#define TIPC_IMPORTANCE 127 /* Default: TIPC_LOW_IMPORTANCE */ -#define TIPC_SRC_DROPPABLE 128 /* Default: 0 (resend congested msg) */ -#define TIPC_DEST_DROPPABLE 129 /* Default: based on socket type */ -#define TIPC_CONN_TIMEOUT 130 /* Default: 8000 (ms) */ - -#endif diff --git a/trunk/include/linux/tipc_config.h b/trunk/include/linux/tipc_config.h deleted file mode 100644 index a52c8c64a5a3..000000000000 --- a/trunk/include/linux/tipc_config.h +++ /dev/null @@ -1,407 +0,0 @@ -/* - * include/linux/tipc_config.h: Include file for TIPC configuration interface - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _LINUX_TIPC_CONFIG_H_ -#define _LINUX_TIPC_CONFIG_H_ - -#include -#include -#include - -/* - * Configuration - * - * All configuration management messaging involves sending a request message - * to the TIPC configuration service on a node, which sends a reply message - * back. (In the future multi-message replies may be supported.) - * - * Both request and reply messages consist of a transport header and payload. - * The transport header contains info about the desired operation; - * the payload consists of zero or more type/length/value (TLV) items - * which specify parameters or results for the operation. - * - * For many operations, the request and reply messages have a fixed number - * of TLVs (usually zero or one); however, some reply messages may return - * a variable number of TLVs. A failed request is denoted by the presence - * of an "error string" TLV in the reply message instead of the TLV(s) the - * reply should contain if the request succeeds. - */ - -/* - * Public commands: - * May be issued by any process. - * Accepted by own node, or by remote node only if remote management enabled. - */ - -#define TIPC_CMD_NOOP 0x0000 /* tx none, rx none */ -#define TIPC_CMD_GET_NODES 0x0001 /* tx net_addr, rx node_info(s) */ -#define TIPC_CMD_GET_MEDIA_NAMES 0x0002 /* tx none, rx media_name(s) */ -#define TIPC_CMD_GET_BEARER_NAMES 0x0003 /* tx none, rx bearer_name(s) */ -#define TIPC_CMD_GET_LINKS 0x0004 /* tx net_addr, rx link_info(s) */ -#define TIPC_CMD_SHOW_NAME_TABLE 0x0005 /* tx name_tbl_query, rx ultra_string */ -#define TIPC_CMD_SHOW_PORTS 0x0006 /* tx none, rx ultra_string */ -#define TIPC_CMD_SHOW_LINK_STATS 0x000B /* tx link_name, rx ultra_string */ - -#if 0 -#define TIPC_CMD_SHOW_PORT_STATS 0x0008 /* tx port_ref, rx ultra_string */ -#define TIPC_CMD_RESET_PORT_STATS 0x0009 /* tx port_ref, rx none */ -#define TIPC_CMD_GET_ROUTES 0x000A /* tx ?, rx ? */ -#define TIPC_CMD_GET_LINK_PEER 0x000D /* tx link_name, rx ? */ -#endif - -/* - * Protected commands: - * May only be issued by "network administration capable" process. - * Accepted by own node, or by remote node only if remote management enabled - * and this node is zone manager. - */ - -#define TIPC_CMD_GET_REMOTE_MNG 0x4003 /* tx none, rx unsigned */ -#define TIPC_CMD_GET_MAX_PORTS 0x4004 /* tx none, rx unsigned */ -#define TIPC_CMD_GET_MAX_PUBL 0x4005 /* tx none, rx unsigned */ -#define TIPC_CMD_GET_MAX_SUBSCR 0x4006 /* tx none, rx unsigned */ -#define TIPC_CMD_GET_MAX_ZONES 0x4007 /* tx none, rx unsigned */ -#define TIPC_CMD_GET_MAX_CLUSTERS 0x4008 /* tx none, rx unsigned */ -#define TIPC_CMD_GET_MAX_NODES 0x4009 /* tx none, rx unsigned */ -#define TIPC_CMD_GET_MAX_SLAVES 0x400A /* tx none, rx unsigned */ -#define TIPC_CMD_GET_NETID 0x400B /* tx none, rx unsigned */ - -#define TIPC_CMD_ENABLE_BEARER 0x4101 /* tx bearer_config, rx none */ -#define TIPC_CMD_DISABLE_BEARER 0x4102 /* tx bearer_name, rx none */ -#define TIPC_CMD_SET_LINK_TOL 0x4107 /* tx link_config, rx none */ -#define TIPC_CMD_SET_LINK_PRI 0x4108 /* tx link_config, rx none */ -#define TIPC_CMD_SET_LINK_WINDOW 0x4109 /* tx link_config, rx none */ -#define TIPC_CMD_SET_LOG_SIZE 0x410A /* tx unsigned, rx none */ -#define TIPC_CMD_DUMP_LOG 0x410B /* tx none, rx ultra_string */ -#define TIPC_CMD_RESET_LINK_STATS 0x410C /* tx link_name, rx none */ - -#if 0 -#define TIPC_CMD_CREATE_LINK 0x4103 /* tx link_create, rx none */ -#define TIPC_CMD_REMOVE_LINK 0x4104 /* tx link_name, rx none */ -#define TIPC_CMD_BLOCK_LINK 0x4105 /* tx link_name, rx none */ -#define TIPC_CMD_UNBLOCK_LINK 0x4106 /* tx link_name, rx none */ -#endif - -/* - * Private commands: - * May only be issued by "network administration capable" process. - * Accepted by own node only; cannot be used on a remote node. - */ - -#define TIPC_CMD_SET_NODE_ADDR 0x8001 /* tx net_addr, rx none */ -#if 0 -#define TIPC_CMD_SET_ZONE_MASTER 0x8002 /* tx none, rx none */ -#endif -#define TIPC_CMD_SET_REMOTE_MNG 0x8003 /* tx unsigned, rx none */ -#define TIPC_CMD_SET_MAX_PORTS 0x8004 /* tx unsigned, rx none */ -#define TIPC_CMD_SET_MAX_PUBL 0x8005 /* tx unsigned, rx none */ -#define TIPC_CMD_SET_MAX_SUBSCR 0x8006 /* tx unsigned, rx none */ -#define TIPC_CMD_SET_MAX_ZONES 0x8007 /* tx unsigned, rx none */ -#define TIPC_CMD_SET_MAX_CLUSTERS 0x8008 /* tx unsigned, rx none */ -#define TIPC_CMD_SET_MAX_NODES 0x8009 /* tx unsigned, rx none */ -#define TIPC_CMD_SET_MAX_SLAVES 0x800A /* tx unsigned, rx none */ -#define TIPC_CMD_SET_NETID 0x800B /* tx unsigned, rx none */ - -/* - * TLV types defined for TIPC - */ - -#define TIPC_TLV_NONE 0 /* no TLV present */ -#define TIPC_TLV_VOID 1 /* empty TLV (0 data bytes)*/ -#define TIPC_TLV_UNSIGNED 2 /* 32-bit integer */ -#define TIPC_TLV_STRING 3 /* char[128] (max) */ -#define TIPC_TLV_LARGE_STRING 4 /* char[2048] (max) */ -#define TIPC_TLV_ULTRA_STRING 5 /* char[32768] (max) */ - -#define TIPC_TLV_ERROR_STRING 16 /* char[128] containing "error code" */ -#define TIPC_TLV_NET_ADDR 17 /* 32-bit integer denoting */ -#define TIPC_TLV_MEDIA_NAME 18 /* char[TIPC_MAX_MEDIA_NAME] */ -#define TIPC_TLV_BEARER_NAME 19 /* char[TIPC_MAX_BEARER_NAME] */ -#define TIPC_TLV_LINK_NAME 20 /* char[TIPC_MAX_LINK_NAME] */ -#define TIPC_TLV_NODE_INFO 21 /* struct tipc_node_info */ -#define TIPC_TLV_LINK_INFO 22 /* struct tipc_link_info */ -#define TIPC_TLV_BEARER_CONFIG 23 /* struct tipc_bearer_config */ -#define TIPC_TLV_LINK_CONFIG 24 /* struct tipc_link_config */ -#define TIPC_TLV_NAME_TBL_QUERY 25 /* struct tipc_name_table_query */ -#define TIPC_TLV_PORT_REF 26 /* 32-bit port reference */ - -/* - * Maximum sizes of TIPC bearer-related names (including terminating NUL) - */ - -#define TIPC_MAX_MEDIA_NAME 16 /* format = media */ -#define TIPC_MAX_IF_NAME 16 /* format = interface */ -#define TIPC_MAX_BEARER_NAME 32 /* format = media:interface */ -#define TIPC_MAX_LINK_NAME 60 /* format = Z.C.N:interface-Z.C.N:interface */ - -/* - * Link priority limits (range from 0 to # priorities - 1) - */ - -#define TIPC_NUM_LINK_PRI 32 - -/* - * Link tolerance limits (min, default, max), in ms - */ - -#define TIPC_MIN_LINK_TOL 50 -#define TIPC_DEF_LINK_TOL 1500 -#define TIPC_MAX_LINK_TOL 30000 - -/* - * Link window limits (min, default, max), in packets - */ - -#define TIPC_MIN_LINK_WIN 16 -#define TIPC_DEF_LINK_WIN 50 -#define TIPC_MAX_LINK_WIN 150 - - -struct tipc_node_info { - __u32 addr; /* network address of node */ - __u32 up; /* 0=down, 1= up */ -}; - -struct tipc_link_info { - __u32 dest; /* network address of peer node */ - __u32 up; /* 0=down, 1=up */ - char str[TIPC_MAX_LINK_NAME]; /* link name */ -}; - -struct tipc_bearer_config { - __u32 priority; /* Range [1,31]. Override per link */ - __u32 detect_scope; - char name[TIPC_MAX_BEARER_NAME]; -}; - -struct tipc_link_config { - __u32 value; - char name[TIPC_MAX_LINK_NAME]; -}; - -#define TIPC_NTQ_ALLTYPES 0x80000000 - -struct tipc_name_table_query { - __u32 depth; /* 1:type, 2:+name info, 3:+port info, 4+:+debug info */ - __u32 type; /* {t,l,u} info ignored if high bit of "depth" is set */ - __u32 lowbound; /* (i.e. displays all entries of name table) */ - __u32 upbound; -}; - -/* - * The error string TLV is a null-terminated string describing the cause - * of the request failure. To simplify error processing (and to save space) - * the first character of the string can be a special error code character - * (lying by the range 0x80 to 0xFF) which represents a pre-defined reason. - */ - -#define TIPC_CFG_TLV_ERROR "\x80" /* request contains incorrect TLV(s) */ -#define TIPC_CFG_NOT_NET_ADMIN "\x81" /* must be network administrator */ -#define TIPC_CFG_NOT_ZONE_MSTR "\x82" /* must be zone master */ -#define TIPC_CFG_NO_REMOTE "\x83" /* remote management not enabled */ -#define TIPC_CFG_NOT_SUPPORTED "\x84" /* request is not supported by TIPC */ -#define TIPC_CFG_INVALID_VALUE "\x85" /* request has invalid argument value */ - -#if 0 -/* prototypes TLV structures for proposed commands */ -struct tipc_link_create { - __u32 domain; - struct tipc_media_addr peer_addr; - char bearer_name[TIPC_MAX_BEARER_NAME]; -}; - -struct tipc_route_info { - __u32 dest; - __u32 router; -}; -#endif - -/* - * A TLV consists of a descriptor, followed by the TLV value. - * TLV descriptor fields are stored in network byte order; - * TLV values must also be stored in network byte order (where applicable). - * TLV descriptors must be aligned to addresses which are multiple of 4, - * so up to 3 bytes of padding may exist at the end of the TLV value area. - * There must not be any padding between the TLV descriptor and its value. - */ - -struct tlv_desc { - __u16 tlv_len; /* TLV length (descriptor + value) */ - __u16 tlv_type; /* TLV identifier */ -}; - -#define TLV_ALIGNTO 4 - -#define TLV_ALIGN(datalen) (((datalen)+(TLV_ALIGNTO-1)) & ~(TLV_ALIGNTO-1)) -#define TLV_LENGTH(datalen) (sizeof(struct tlv_desc) + (datalen)) -#define TLV_SPACE(datalen) (TLV_ALIGN(TLV_LENGTH(datalen))) -#define TLV_DATA(tlv) ((void *)((char *)(tlv) + TLV_LENGTH(0))) - -static inline int TLV_OK(const void *tlv, __u16 space) -{ - /* - * Would also like to check that "tlv" is a multiple of 4, - * but don't know how to do this in a portable way. - * - Tried doing (!(tlv & (TLV_ALIGNTO-1))), but GCC compiler - * won't allow binary "&" with a pointer. - * - Tried casting "tlv" to integer type, but causes warning about size - * mismatch when pointer is bigger than chosen type (int, long, ...). - */ - - return (space >= TLV_SPACE(0)) && - (ntohs(((struct tlv_desc *)tlv)->tlv_len) <= space); -} - -static inline int TLV_CHECK(const void *tlv, __u16 space, __u16 exp_type) -{ - return TLV_OK(tlv, space) && - (ntohs(((struct tlv_desc *)tlv)->tlv_type) == exp_type); -} - -static inline int TLV_SET(void *tlv, __u16 type, void *data, __u16 len) -{ - struct tlv_desc *tlv_ptr; - int tlv_len; - - tlv_len = TLV_LENGTH(len); - tlv_ptr = (struct tlv_desc *)tlv; - tlv_ptr->tlv_type = htons(type); - tlv_ptr->tlv_len = htons(tlv_len); - if (len && data) - memcpy(TLV_DATA(tlv_ptr), data, tlv_len); - return TLV_SPACE(len); -} - -/* - * A TLV list descriptor simplifies processing of messages - * containing multiple TLVs. - */ - -struct tlv_list_desc { - struct tlv_desc *tlv_ptr; /* ptr to current TLV */ - __u32 tlv_space; /* # bytes from curr TLV to list end */ -}; - -static inline void TLV_LIST_INIT(struct tlv_list_desc *list, - void *data, __u32 space) -{ - list->tlv_ptr = (struct tlv_desc *)data; - list->tlv_space = space; -} - -static inline int TLV_LIST_EMPTY(struct tlv_list_desc *list) -{ - return (list->tlv_space == 0); -} - -static inline int TLV_LIST_CHECK(struct tlv_list_desc *list, __u16 exp_type) -{ - return TLV_CHECK(list->tlv_ptr, list->tlv_space, exp_type); -} - -static inline void *TLV_LIST_DATA(struct tlv_list_desc *list) -{ - return TLV_DATA(list->tlv_ptr); -} - -static inline void TLV_LIST_STEP(struct tlv_list_desc *list) -{ - __u16 tlv_space = TLV_ALIGN(ntohs(list->tlv_ptr->tlv_len)); - - list->tlv_ptr = (struct tlv_desc *)((char *)list->tlv_ptr + tlv_space); - list->tlv_space -= tlv_space; -} - -/* - * Configuration messages exchanged via NETLINK_GENERIC use the following - * family id, name, version and command. - */ -#define TIPC_GENL_NAME "TIPC" -#define TIPC_GENL_VERSION 0x1 -#define TIPC_GENL_CMD 0x1 - -/* - * TIPC specific header used in NETLINK_GENERIC requests. - */ -struct tipc_genlmsghdr { - __u32 dest; /* Destination address */ - __u16 cmd; /* Command */ - __u16 reserved; /* Unused */ -}; - -#define TIPC_GENL_HDRLEN NLMSG_ALIGN(sizeof(struct tipc_genlmsghdr)) - -/* - * Configuration messages exchanged via TIPC sockets use the TIPC configuration - * message header, which is defined below. This structure is analogous - * to the Netlink message header, but fields are stored in network byte order - * and no padding is permitted between the header and the message data - * that follows. - */ - -struct tipc_cfg_msg_hdr -{ - __u32 tcm_len; /* Message length (including header) */ - __u16 tcm_type; /* Command type */ - __u16 tcm_flags; /* Additional flags */ - char tcm_reserved[8]; /* Unused */ -}; - -#define TCM_F_REQUEST 0x1 /* Flag: Request message */ -#define TCM_F_MORE 0x2 /* Flag: Message to be continued */ - -#define TCM_ALIGN(datalen) (((datalen)+3) & ~3) -#define TCM_LENGTH(datalen) (sizeof(struct tipc_cfg_msg_hdr) + datalen) -#define TCM_SPACE(datalen) (TCM_ALIGN(TCM_LENGTH(datalen))) -#define TCM_DATA(tcm_hdr) ((void *)((char *)(tcm_hdr) + TCM_LENGTH(0))) - -static inline int TCM_SET(void *msg, __u16 cmd, __u16 flags, - void *data, __u16 data_len) -{ - struct tipc_cfg_msg_hdr *tcm_hdr; - int msg_len; - - msg_len = TCM_LENGTH(data_len); - tcm_hdr = (struct tipc_cfg_msg_hdr *)msg; - tcm_hdr->tcm_len = htonl(msg_len); - tcm_hdr->tcm_type = htons(cmd); - tcm_hdr->tcm_flags = htons(flags); - if (data_len && data) - memcpy(TCM_DATA(msg), data, data_len); - return TCM_SPACE(data_len); -} - -#endif diff --git a/trunk/include/net/genetlink.h b/trunk/include/net/genetlink.h index 805de50df00d..c5b96b2b8155 100644 --- a/trunk/include/net/genetlink.h +++ b/trunk/include/net/genetlink.h @@ -22,6 +22,7 @@ struct genl_family char name[GENL_NAMSIZ]; unsigned int version; unsigned int maxattr; + struct module * owner; struct nlattr ** attrbuf; /* private */ struct list_head ops_list; /* private */ struct list_head family_list; /* private */ diff --git a/trunk/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/trunk/include/net/netfilter/ipv4/nf_conntrack_ipv4.h index 91684436af8e..25b081a730e6 100644 --- a/trunk/include/net/netfilter/ipv4/nf_conntrack_ipv4.h +++ b/trunk/include/net/netfilter/ipv4/nf_conntrack_ipv4.h @@ -37,4 +37,7 @@ struct nf_conntrack_ipv4 { struct sk_buff * nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb); +/* call to create an explicit dependency on nf_conntrack_l3proto_ipv4. */ +extern void need_ip_conntrack(void); + #endif /*_NF_CONNTRACK_IPV4_H*/ diff --git a/trunk/include/net/netfilter/nf_conntrack.h b/trunk/include/net/netfilter/nf_conntrack.h index 6d075ca16e6e..64b82b74a650 100644 --- a/trunk/include/net/netfilter/nf_conntrack.h +++ b/trunk/include/net/netfilter/nf_conntrack.h @@ -221,6 +221,9 @@ extern void nf_ct_helper_put(struct nf_conntrack_helper *helper); extern struct nf_conntrack_helper * __nf_conntrack_helper_find_byname(const char *name); +/* call to create an explicit dependency on nf_conntrack. */ +extern void need_nf_conntrack(void); + extern int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, const struct nf_conntrack_tuple *orig); diff --git a/trunk/include/net/netfilter/nf_conntrack_tuple.h b/trunk/include/net/netfilter/nf_conntrack_tuple.h index 530ef1f75283..14ce790e5c65 100644 --- a/trunk/include/net/netfilter/nf_conntrack_tuple.h +++ b/trunk/include/net/netfilter/nf_conntrack_tuple.h @@ -111,7 +111,7 @@ struct nf_conntrack_tuple #ifdef __KERNEL__ #define NF_CT_DUMP_TUPLE(tp) \ -DEBUGP("tuple %p: %u %u " NIP6_FMT " %hu -> " NIP6_FMT " %hu\n", \ +DEBUGP("tuple %p: %u %u %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu -> %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %hu\n", \ (tp), (tp)->src.l3num, (tp)->dst.protonum, \ NIP6(*(struct in6_addr *)(tp)->src.u3.all), ntohs((tp)->src.u.all), \ NIP6(*(struct in6_addr *)(tp)->dst.u3.all), ntohs((tp)->dst.u.all)) diff --git a/trunk/include/net/sctp/sctp.h b/trunk/include/net/sctp/sctp.h index a553f39f6aee..8f241216f46b 100644 --- a/trunk/include/net/sctp/sctp.h +++ b/trunk/include/net/sctp/sctp.h @@ -225,13 +225,13 @@ extern int sctp_debug_flag; if (sctp_debug_flag) { \ if (saddr->sa.sa_family == AF_INET6) { \ printk(KERN_DEBUG \ - lead NIP6_FMT trail, \ + lead "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" trail, \ leadparm, \ NIP6(saddr->v6.sin6_addr), \ otherparms); \ } else { \ printk(KERN_DEBUG \ - lead NIPQUAD_FMT trail, \ + lead "%u.%u.%u.%u" trail, \ leadparm, \ NIPQUAD(saddr->v4.sin_addr.s_addr), \ otherparms); \ diff --git a/trunk/include/net/tipc/tipc.h b/trunk/include/net/tipc/tipc.h deleted file mode 100644 index 9566608c88cf..000000000000 --- a/trunk/include/net/tipc/tipc.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * include/net/tipc/tipc.h: Main include file for TIPC users - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _NET_TIPC_H_ -#define _NET_TIPC_H_ - -#ifdef __KERNEL__ - -#include -#include - -/* - * Native API - */ - -/* - * TIPC operating mode routines - */ - -u32 tipc_get_addr(void); - -#define TIPC_NOT_RUNNING 0 -#define TIPC_NODE_MODE 1 -#define TIPC_NET_MODE 2 - -typedef void (*tipc_mode_event)(void *usr_handle, int mode, u32 addr); - -int tipc_attach(unsigned int *userref, tipc_mode_event, void *usr_handle); - -void tipc_detach(unsigned int userref); - -int tipc_get_mode(void); - -/* - * TIPC port manipulation routines - */ - -typedef void (*tipc_msg_err_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - int reason, - struct tipc_portid const *attmpt_destid); - -typedef void (*tipc_named_msg_err_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - int reason, - struct tipc_name_seq const *attmpt_dest); - -typedef void (*tipc_conn_shutdown_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - int reason); - -typedef void (*tipc_msg_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - unsigned int importance, - struct tipc_portid const *origin); - -typedef void (*tipc_named_msg_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - unsigned int importance, - struct tipc_portid const *orig, - struct tipc_name_seq const *dest); - -typedef void (*tipc_conn_msg_event) (void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size); - -typedef void (*tipc_continue_event) (void *usr_handle, - u32 portref); - -int tipc_createport(unsigned int tipc_user, - void *usr_handle, - unsigned int importance, - tipc_msg_err_event error_cb, - tipc_named_msg_err_event named_error_cb, - tipc_conn_shutdown_event conn_error_cb, - tipc_msg_event message_cb, - tipc_named_msg_event named_message_cb, - tipc_conn_msg_event conn_message_cb, - tipc_continue_event continue_event_cb,/* May be zero */ - u32 *portref); - -int tipc_deleteport(u32 portref); - -int tipc_ownidentity(u32 portref, struct tipc_portid *port); - -int tipc_portimportance(u32 portref, unsigned int *importance); -int tipc_set_portimportance(u32 portref, unsigned int importance); - -int tipc_portunreliable(u32 portref, unsigned int *isunreliable); -int tipc_set_portunreliable(u32 portref, unsigned int isunreliable); - -int tipc_portunreturnable(u32 portref, unsigned int *isunreturnable); -int tipc_set_portunreturnable(u32 portref, unsigned int isunreturnable); - -int tipc_publish(u32 portref, unsigned int scope, - struct tipc_name_seq const *name_seq); -int tipc_withdraw(u32 portref, unsigned int scope, - struct tipc_name_seq const *name_seq); /* 0: all */ - -int tipc_connect2port(u32 portref, struct tipc_portid const *port); - -int tipc_disconnect(u32 portref); - -int tipc_shutdown(u32 ref); /* Sends SHUTDOWN msg */ - -int tipc_isconnected(u32 portref, int *isconnected); - -int tipc_peer(u32 portref, struct tipc_portid *peer); - -int tipc_ref_valid(u32 portref); - -/* - * TIPC messaging routines - */ - -#define TIPC_PORT_IMPORTANCE 100 /* send using current port setting */ - - -int tipc_send(u32 portref, - unsigned int num_sect, - struct iovec const *msg_sect); - -int tipc_send_buf(u32 portref, - struct sk_buff *buf, - unsigned int dsz); - -int tipc_send2name(u32 portref, - struct tipc_name const *name, - u32 domain, /* 0:own zone */ - unsigned int num_sect, - struct iovec const *msg_sect); - -int tipc_send_buf2name(u32 portref, - struct tipc_name const *name, - u32 domain, - struct sk_buff *buf, - unsigned int dsz); - -int tipc_forward2name(u32 portref, - struct tipc_name const *name, - u32 domain, /*0: own zone */ - unsigned int section_count, - struct iovec const *msg_sect, - struct tipc_portid const *origin, - unsigned int importance); - -int tipc_forward_buf2name(u32 portref, - struct tipc_name const *name, - u32 domain, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance); - -int tipc_send2port(u32 portref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect); - -int tipc_send_buf2port(u32 portref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz); - -int tipc_forward2port(u32 portref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *origin, - unsigned int importance); - -int tipc_forward_buf2port(u32 portref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance); - -int tipc_multicast(u32 portref, - struct tipc_name_seq const *seq, - u32 domain, /* 0:own zone */ - unsigned int section_count, - struct iovec const *msg); - -#if 0 -int tipc_multicast_buf(u32 portref, - struct tipc_name_seq const *seq, - u32 domain, /* 0:own zone */ - void *buf, - unsigned int size); -#endif - -/* - * TIPC subscription routines - */ - -int tipc_ispublished(struct tipc_name const *name); - -/* - * Get number of available nodes within specified domain (excluding own node) - */ - -unsigned int tipc_available_nodes(const u32 domain); - -#endif - -#endif diff --git a/trunk/include/net/tipc/tipc_bearer.h b/trunk/include/net/tipc/tipc_bearer.h deleted file mode 100644 index 098607cd4b78..000000000000 --- a/trunk/include/net/tipc/tipc_bearer.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * include/net/tipc/tipc_bearer.h: Include file for privileged access to TIPC bearers - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _NET_TIPC_BEARER_H_ -#define _NET_TIPC_BEARER_H_ - -#ifdef __KERNEL__ - -#include -#include -#include - -/* - * Identifiers of supported TIPC media types - */ - -#define TIPC_MEDIA_TYPE_ETH 1 - -struct tipc_media_addr { - __u32 type; - union { - __u8 eth_addr[6]; /* Ethernet bearer */ -#if 0 - /* Prototypes for other possible bearer types */ - - struct { - __u16 sin_family; - __u16 sin_port; - struct { - __u32 s_addr; - } sin_addr; - char pad[4]; - } addr_in; /* IP-based bearer */ - __u16 sock_descr; /* generic socket bearer */ -#endif - } dev_addr; -}; - -/** - * struct tipc_bearer - TIPC bearer info available to privileged users - * @usr_handle: pointer to additional user-defined information about bearer - * @mtu: max packet size bearer can support - * @blocked: non-zero if bearer is blocked - * @lock: spinlock for controlling access to bearer - * @addr: media-specific address associated with bearer - * @name: bearer name (format = media:interface) - * - * Note: TIPC initializes "name" and "lock" fields; user is responsible for - * initialization all other fields when a bearer is enabled. - */ - -struct tipc_bearer { - void *usr_handle; - u32 mtu; - int blocked; - spinlock_t lock; - struct tipc_media_addr addr; - char name[TIPC_MAX_BEARER_NAME]; -}; - - -int tipc_register_media(u32 media_type, - char *media_name, - int (*enable)(struct tipc_bearer *), - void (*disable)(struct tipc_bearer *), - int (*send_msg)(struct sk_buff *, - struct tipc_bearer *, - struct tipc_media_addr *), - char *(*addr2str)(struct tipc_media_addr *a, - char *str_buf, - int str_size), - struct tipc_media_addr *bcast_addr, - const u32 bearer_priority, - const u32 link_tolerance, /* [ms] */ - const u32 send_window_limit); - -void tipc_recv_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr); - -int tipc_block_bearer(const char *name); -void tipc_continue(struct tipc_bearer *tb_ptr); - -int tipc_enable_bearer(const char *bearer_name, u32 bcast_scope, u32 priority); -int tipc_disable_bearer(const char *name); - - -#endif - -#endif diff --git a/trunk/include/net/tipc/tipc_msg.h b/trunk/include/net/tipc/tipc_msg.h deleted file mode 100644 index 4d096eebc93f..000000000000 --- a/trunk/include/net/tipc/tipc_msg.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * include/net/tipc/tipc_msg.h: Include file for privileged access to TIPC message headers - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _NET_TIPC_MSG_H_ -#define _NET_TIPC_MSG_H_ - -#ifdef __KERNEL__ - -struct tipc_msg { - u32 hdr[15]; -}; - - -/* - TIPC user data message header format, version 2: - - - 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w0:|vers | user |hdr sz |n|d|s|-| message size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w1:|mstyp| error |rer cnt|lsc|opt p| broadcast ack no | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w2:| link level ack no | broadcast/link level seq no | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w3:| previous node | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w4:| originating port | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w5:| destination port | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w6:| originating node | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w7:| destination node | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w8:| name type / transport sequence number | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w9:| name instance/multicast lower bound | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - wA:| multicast upper bound | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - / / - \ options \ - / / - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - -*/ - -#define TIPC_CONN_MSG 0 -#define TIPC_MCAST_MSG 1 -#define TIPC_NAMED_MSG 2 -#define TIPC_DIRECT_MSG 3 - - -static inline u32 msg_word(struct tipc_msg *m, u32 pos) -{ - return ntohl(m->hdr[pos]); -} - -static inline u32 msg_bits(struct tipc_msg *m, u32 w, u32 pos, u32 mask) -{ - return (msg_word(m, w) >> pos) & mask; -} - -static inline u32 msg_importance(struct tipc_msg *m) -{ - return msg_bits(m, 0, 25, 0xf); -} - -static inline u32 msg_hdr_sz(struct tipc_msg *m) -{ - return msg_bits(m, 0, 21, 0xf) << 2; -} - -static inline int msg_short(struct tipc_msg *m) -{ - return (msg_hdr_sz(m) == 24); -} - -static inline u32 msg_size(struct tipc_msg *m) -{ - return msg_bits(m, 0, 0, 0x1ffff); -} - -static inline u32 msg_data_sz(struct tipc_msg *m) -{ - return (msg_size(m) - msg_hdr_sz(m)); -} - -static inline unchar *msg_data(struct tipc_msg *m) -{ - return ((unchar *)m) + msg_hdr_sz(m); -} - -static inline u32 msg_type(struct tipc_msg *m) -{ - return msg_bits(m, 1, 29, 0x7); -} - -static inline u32 msg_direct(struct tipc_msg *m) -{ - return (msg_type(m) == TIPC_DIRECT_MSG); -} - -static inline u32 msg_named(struct tipc_msg *m) -{ - return (msg_type(m) == TIPC_NAMED_MSG); -} - -static inline u32 msg_mcast(struct tipc_msg *m) -{ - return (msg_type(m) == TIPC_MCAST_MSG); -} - -static inline u32 msg_connected(struct tipc_msg *m) -{ - return (msg_type(m) == TIPC_CONN_MSG); -} - -static inline u32 msg_errcode(struct tipc_msg *m) -{ - return msg_bits(m, 1, 25, 0xf); -} - -static inline u32 msg_prevnode(struct tipc_msg *m) -{ - return msg_word(m, 3); -} - -static inline u32 msg_origport(struct tipc_msg *m) -{ - return msg_word(m, 4); -} - -static inline u32 msg_destport(struct tipc_msg *m) -{ - return msg_word(m, 5); -} - -static inline u32 msg_mc_netid(struct tipc_msg *m) -{ - return msg_word(m, 5); -} - -static inline u32 msg_orignode(struct tipc_msg *m) -{ - if (likely(msg_short(m))) - return msg_prevnode(m); - return msg_word(m, 6); -} - -static inline u32 msg_destnode(struct tipc_msg *m) -{ - return msg_word(m, 7); -} - -static inline u32 msg_nametype(struct tipc_msg *m) -{ - return msg_word(m, 8); -} - -static inline u32 msg_nameinst(struct tipc_msg *m) -{ - return msg_word(m, 9); -} - -static inline u32 msg_namelower(struct tipc_msg *m) -{ - return msg_nameinst(m); -} - -static inline u32 msg_nameupper(struct tipc_msg *m) -{ - return msg_word(m, 10); -} - -static inline char *msg_options(struct tipc_msg *m, u32 *len) -{ - u32 pos = msg_bits(m, 1, 16, 0x7); - - if (!pos) - return 0; - pos = (pos * 4) + 28; - *len = msg_hdr_sz(m) - pos; - return (char *)&m->hdr[pos/4]; -} - -#endif - -#endif diff --git a/trunk/include/net/tipc/tipc_port.h b/trunk/include/net/tipc/tipc_port.h deleted file mode 100644 index 333bba6dc522..000000000000 --- a/trunk/include/net/tipc/tipc_port.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * include/net/tipc/tipc_port.h: Include file for privileged access to TIPC ports - * - * Copyright (c) 1994-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _NET_TIPC_PORT_H_ -#define _NET_TIPC_PORT_H_ - -#ifdef __KERNEL__ - -#include -#include -#include - -#define TIPC_FLOW_CONTROL_WIN 512 - -/** - * struct tipc_port - native TIPC port info available to privileged users - * @usr_handle: pointer to additional user-defined information about port - * @lock: pointer to spinlock for controlling access to port - * @connected: non-zero if port is currently connected to a peer port - * @conn_type: TIPC type used when connection was established - * @conn_instance: TIPC instance used when connection was established - * @conn_unacked: number of unacknowledged messages received from peer port - * @published: non-zero if port has one or more associated names - * @congested: non-zero if cannot send because of link or port congestion - * @ref: unique reference to port in TIPC object registry - * @phdr: preformatted message header used when sending messages - */ - -struct tipc_port { - void *usr_handle; - spinlock_t *lock; - int connected; - u32 conn_type; - u32 conn_instance; - u32 conn_unacked; - int published; - u32 congested; - u32 ref; - struct tipc_msg phdr; -}; - - -/** - * tipc_createport_raw - create a native TIPC port and return it's reference - * - * Note: 'dispatcher' and 'wakeup' deliver a locked port. - */ - -u32 tipc_createport_raw(void *usr_handle, - u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), - void (*wakeup)(struct tipc_port *), - const u32 importance); - -/* - * tipc_set_msg_option(): port must be locked. - */ -int tipc_set_msg_option(struct tipc_port *tp_ptr, - const char *opt, - const u32 len); - -int tipc_reject_msg(struct sk_buff *buf, u32 err); - -int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode); - -void tipc_acknowledge(u32 port_ref,u32 ack); - -struct tipc_port *tipc_get_port(const u32 ref); - -void *tipc_get_handle(const u32 ref); - - -#endif - -#endif - diff --git a/trunk/include/rdma/ib_verbs.h b/trunk/include/rdma/ib_verbs.h index 22fc886b9695..a7f4c355a91f 100644 --- a/trunk/include/rdma/ib_verbs.h +++ b/trunk/include/rdma/ib_verbs.h @@ -88,6 +88,7 @@ enum ib_atomic_cap { struct ib_device_attr { u64 fw_ver; + __be64 node_guid; __be64 sys_image_guid; u64 max_mr_size; u64 page_size_cap; @@ -950,7 +951,6 @@ struct ib_device { u64 uverbs_cmd_mask; int uverbs_abi_ver; - __be64 node_guid; u8 node_type; u8 phys_port_cnt; }; diff --git a/trunk/net/Kconfig b/trunk/net/Kconfig index 9296b269d675..60f6f321bd76 100644 --- a/trunk/net/Kconfig +++ b/trunk/net/Kconfig @@ -159,7 +159,6 @@ source "net/ipx/Kconfig" source "drivers/net/appletalk/Kconfig" source "net/x25/Kconfig" source "net/lapb/Kconfig" -source "net/tipc/Kconfig" config NET_DIVERT bool "Frame Diverter (EXPERIMENTAL)" diff --git a/trunk/net/Makefile b/trunk/net/Makefile index 065796f5fb17..f5141b9d4f38 100644 --- a/trunk/net/Makefile +++ b/trunk/net/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_VLAN_8021Q) += 8021q/ obj-$(CONFIG_IP_DCCP) += dccp/ obj-$(CONFIG_IP_SCTP) += sctp/ obj-$(CONFIG_IEEE80211) += ieee80211/ -obj-$(CONFIG_TIPC) += tipc/ ifeq ($(CONFIG_NET),y) obj-$(CONFIG_SYSCTL) += sysctl_net.o diff --git a/trunk/net/bridge/netfilter/ebt_log.c b/trunk/net/bridge/netfilter/ebt_log.c index a29c1232c420..9f6e0193ae10 100644 --- a/trunk/net/bridge/netfilter/ebt_log.c +++ b/trunk/net/bridge/netfilter/ebt_log.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/trunk/net/core/filter.c b/trunk/net/core/filter.c index a52665f75224..9eb9d0017a01 100644 --- a/trunk/net/core/filter.c +++ b/trunk/net/core/filter.c @@ -287,9 +287,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int * no references or jumps that are out of range, no illegal * instructions, and must end with a RET instruction. * - * All jumps are forward as they are not signed. - * - * Returns 0 if the rule set is legal or -EINVAL if not. + * Returns 0 if the rule set is legal or a negative errno code if not. */ int sk_chk_filter(struct sock_filter *filter, int flen) { @@ -301,6 +299,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen) /* check the filter code now */ for (pc = 0; pc < flen; pc++) { + /* all jumps are forward as they are not signed */ ftest = &filter[pc]; /* Only allow valid instructions */ @@ -384,6 +383,11 @@ int sk_chk_filter(struct sock_filter *filter, int flen) } } + /* + * The program must end with a return. We don't care where they + * jumped within the script (its always forwards) but in the end + * they _will_ hit this. + */ return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL; } diff --git a/trunk/net/ipv4/netfilter/Kconfig b/trunk/net/ipv4/netfilter/Kconfig index db783036e4d8..a9893ec03e02 100644 --- a/trunk/net/ipv4/netfilter/Kconfig +++ b/trunk/net/ipv4/netfilter/Kconfig @@ -182,7 +182,6 @@ config IP_NF_QUEUE config IP_NF_IPTABLES tristate "IP tables support (required for filtering/masq/NAT)" - depends on NETFILTER_XTABLES help iptables is a general, extensible packet identification framework. The packet filtering and full NAT (masquerading, port forwarding, @@ -192,6 +191,16 @@ config IP_NF_IPTABLES To compile it as a module, choose M here. If unsure, say N. # The matches. +config IP_NF_MATCH_LIMIT + tristate "limit match support" + depends on IP_NF_IPTABLES + help + limit matching allows you to control the rate at which a rule can be + matched: mainly useful in combination with the LOG target ("LOG + target support", below) and to avoid some Denial of Service attacks. + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_MATCH_IPRANGE tristate "IP range match support" depends on IP_NF_IPTABLES @@ -201,6 +210,37 @@ config IP_NF_MATCH_IPRANGE To compile it as a module, choose M here. If unsure, say N. +config IP_NF_MATCH_MAC + tristate "MAC address match support" + depends on IP_NF_IPTABLES + help + MAC matching allows you to match packets based on the source + Ethernet address of the packet. + + To compile it as a module, choose M here. If unsure, say N. + +config IP_NF_MATCH_PKTTYPE + tristate "Packet type match support" + depends on IP_NF_IPTABLES + help + Packet type matching allows you to match a packet by + its "class", eg. BROADCAST, MULTICAST, ... + + Typical usage: + iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG + + To compile it as a module, choose M here. If unsure, say N. + +config IP_NF_MATCH_MARK + tristate "netfilter MARK match support" + depends on IP_NF_IPTABLES + help + Netfilter mark matching allows you to match packets based on the + `nfmark' value in the packet. This can be set by the MARK target + (see below). + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_MATCH_MULTIPORT tristate "Multiple port match support" depends on IP_NF_IPTABLES @@ -261,6 +301,15 @@ config IP_NF_MATCH_AH_ESP To compile it as a module, choose M here. If unsure, say N. +config IP_NF_MATCH_LENGTH + tristate "LENGTH match support" + depends on IP_NF_IPTABLES + help + This option allows you to match the length of a packet against a + specific value or range of values. + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_MATCH_TTL tristate "TTL match support" depends on IP_NF_IPTABLES @@ -270,6 +319,50 @@ config IP_NF_MATCH_TTL To compile it as a module, choose M here. If unsure, say N. +config IP_NF_MATCH_TCPMSS + tristate "tcpmss match support" + depends on IP_NF_IPTABLES + help + This option adds a `tcpmss' match, which allows you to examine the + MSS value of TCP SYN packets, which control the maximum packet size + for that connection. + + To compile it as a module, choose M here. If unsure, say N. + +config IP_NF_MATCH_HELPER + tristate "Helper match support" + depends on IP_NF_IPTABLES + depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 + help + Helper matching allows you to match packets in dynamic connections + tracked by a conntrack-helper, ie. ip_conntrack_ftp + + To compile it as a module, choose M here. If unsure, say Y. + +config IP_NF_MATCH_STATE + tristate "Connection state match support" + depends on IP_NF_IPTABLES + depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 + help + Connection state matching allows you to match packets based on their + relationship to a tracked connection (ie. previous packets). This + is a powerful tool for packet classification. + + To compile it as a module, choose M here. If unsure, say N. + +config IP_NF_MATCH_CONNTRACK + tristate "Connection tracking match support" + depends on IP_NF_IPTABLES + depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 + help + This is a general conntrack match module, a superset of the state match. + + It allows matching on additional conntrack information, which is + useful in complex configurations, such as NAT gateways with multiple + internet links or tunnels. + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_MATCH_OWNER tristate "Owner match support" depends on IP_NF_IPTABLES @@ -279,6 +372,15 @@ config IP_NF_MATCH_OWNER To compile it as a module, choose M here. If unsure, say N. +config IP_NF_MATCH_PHYSDEV + tristate "Physdev match support" + depends on IP_NF_IPTABLES && BRIDGE_NETFILTER + help + Physdev packet matching matches against the physical bridge ports + the IP packet arrived on or will leave by. + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_MATCH_ADDRTYPE tristate 'address type match support' depends on IP_NF_IPTABLES @@ -289,6 +391,75 @@ config IP_NF_MATCH_ADDRTYPE If you want to compile it as a module, say M here and read . If unsure, say `N'. +config IP_NF_MATCH_REALM + tristate 'realm match support' + depends on IP_NF_IPTABLES + select NET_CLS_ROUTE + help + This option adds a `realm' match, which allows you to use the realm + key from the routing subsystem inside iptables. + + This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option + in tc world. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +config IP_NF_MATCH_SCTP + tristate 'SCTP protocol match support' + depends on IP_NF_IPTABLES + help + With this option enabled, you will be able to use the iptables + `sctp' match in order to match on SCTP source/destination ports + and SCTP chunk types. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +config IP_NF_MATCH_DCCP + tristate 'DCCP protocol match support' + depends on IP_NF_IPTABLES + help + With this option enabled, you will be able to use the iptables + `dccp' match in order to match on DCCP source/destination ports + and DCCP flags. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +config IP_NF_MATCH_COMMENT + tristate 'comment match support' + depends on IP_NF_IPTABLES + help + This option adds a `comment' dummy-match, which allows you to put + comments in your iptables ruleset. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + +config IP_NF_MATCH_CONNMARK + tristate 'Connection mark match support' + depends on IP_NF_IPTABLES + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) + help + This option adds a `connmark' match, which allows you to match the + connection mark value previously set for the session by `CONNMARK'. + + If you want to compile it as a module, say M here and read + . The module will be called + ipt_connmark.o. If unsure, say `N'. + +config IP_NF_MATCH_CONNBYTES + tristate 'Connection byte/packet counter match support' + depends on IP_NF_IPTABLES + depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK_IPV4) + help + This option adds a `connbytes' match, which allows you to match the + number of bytes and/or packets for each direction within a connection. + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + config IP_NF_MATCH_HASHLIMIT tristate 'hashlimit match support' depends on IP_NF_IPTABLES @@ -303,6 +474,19 @@ config IP_NF_MATCH_HASHLIMIT destination IP' or `500pps from any given source IP' with a single IPtables rule. +config IP_NF_MATCH_STRING + tristate 'string match support' + depends on IP_NF_IPTABLES + select TEXTSEARCH + select TEXTSEARCH_KMP + select TEXTSEARCH_BM + select TEXTSEARCH_FSM + help + This option adds a `string' match, which allows you to look for + pattern matchings in packets. + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_MATCH_POLICY tristate "IPsec policy match support" depends on IP_NF_IPTABLES && XFRM @@ -388,6 +572,17 @@ config IP_NF_TARGET_TCPMSS To compile it as a module, choose M here. If unsure, say N. +config IP_NF_TARGET_NFQUEUE + tristate "NFQUEUE Target Support" + depends on IP_NF_IPTABLES + help + This Target replaced the old obsolete QUEUE target. + + As opposed to QUEUE, it supports 65535 different queues, + not just one. + + To compile it as a module, choose M here. If unsure, say N. + # NAT + specific targets config IP_NF_NAT tristate "Full NAT" @@ -540,6 +735,31 @@ config IP_NF_TARGET_DSCP To compile it as a module, choose M here. If unsure, say N. +config IP_NF_TARGET_MARK + tristate "MARK target support" + depends on IP_NF_MANGLE + help + This option adds a `MARK' target, which allows you to create rules + in the `mangle' table which alter the netfilter mark (nfmark) field + associated with the packet prior to routing. This can change + the routing method (see `Use netfilter MARK value as routing + key') and can also be used by other subsystems to change their + behavior. + + To compile it as a module, choose M here. If unsure, say N. + +config IP_NF_TARGET_CLASSIFY + tristate "CLASSIFY target support" + depends on IP_NF_MANGLE + help + This option adds a `CLASSIFY' target, which enables the user to set + the priority of a packet. Some qdiscs can use this value for + classification, among these are: + + atm, cbq, dsmark, pfifo_fast, htb, prio + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_TARGET_TTL tristate 'TTL target support' depends on IP_NF_MANGLE @@ -554,6 +774,19 @@ config IP_NF_TARGET_TTL To compile it as a module, choose M here. If unsure, say N. +config IP_NF_TARGET_CONNMARK + tristate 'CONNMARK target support' + depends on IP_NF_MANGLE + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) + help + This option adds a `CONNMARK' target, which allows one to manipulate + the connection mark value. Similar to the MARK target, but + affects the connection mark value rather than the packet mark value. + + If you want to compile it as a module, say M here and read + . The module will be called + ipt_CONNMARK.o. If unsure, say `N'. + config IP_NF_TARGET_CLUSTERIP tristate "CLUSTERIP target support (EXPERIMENTAL)" depends on IP_NF_MANGLE && EXPERIMENTAL @@ -577,10 +810,23 @@ config IP_NF_RAW If you want to compile it as a module, say M here and read . If unsure, say `N'. +config IP_NF_TARGET_NOTRACK + tristate 'NOTRACK target support' + depends on IP_NF_RAW + depends on IP_NF_CONNTRACK || NF_CONNTRACK_IPV4 + help + The NOTRACK target allows a select rule to specify + which packets *not* to enter the conntrack/NAT + subsystem with all the consequences (no ICMP error tracking, + no protocol helpers for the selected packets). + + If you want to compile it as a module, say M here and read + . If unsure, say `N'. + + # ARP tables config IP_NF_ARPTABLES tristate "ARP tables support" - depends on NETFILTER_XTABLES help arptables is a general, extensible packet identification framework. The ARP packet filtering and mangling (manipulation)subsystems diff --git a/trunk/net/ipv4/netfilter/Makefile b/trunk/net/ipv4/netfilter/Makefile index bcefe64b9317..549b01a648b3 100644 --- a/trunk/net/ipv4/netfilter/Makefile +++ b/trunk/net/ipv4/netfilter/Makefile @@ -47,8 +47,14 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o # matches obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o +obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o +obj-$(CONFIG_IP_NF_MATCH_SCTP) += ipt_sctp.o +obj-$(CONFIG_IP_NF_MATCH_DCCP) += ipt_dccp.o +obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o +obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o +obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o @@ -56,25 +62,40 @@ obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o +obj-$(CONFIG_IP_NF_MATCH_LENGTH) += ipt_length.o obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o +obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o +obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o +obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o +obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o +obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o +obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o +obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o +obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o +obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o # targets obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o obj-$(CONFIG_IP_NF_TARGET_DSCP) += ipt_DSCP.o +obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o +obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o +obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o +obj-$(CONFIG_IP_NF_TARGET_NOTRACK) += ipt_NOTRACK.o obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o +obj-$(CONFIG_IP_NF_TARGET_NFQUEUE) += ipt_NFQUEUE.o # generic ARP tables obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o diff --git a/trunk/net/ipv4/netfilter/arp_tables.c b/trunk/net/ipv4/netfilter/arp_tables.c index afe3d8f8177d..b6d5284c8020 100644 --- a/trunk/net/ipv4/netfilter/arp_tables.c +++ b/trunk/net/ipv4/netfilter/arp_tables.c @@ -24,7 +24,6 @@ #include #include -#include #include MODULE_LICENSE("GPL"); @@ -56,9 +55,28 @@ do { \ #else #define ARP_NF_ASSERT(x) #endif +#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) +static DECLARE_MUTEX(arpt_mutex); + +#define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) +#define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0) #include +struct arpt_table_info { + unsigned int size; + unsigned int number; + unsigned int initial_entries; + unsigned int hook_entry[NF_ARP_NUMHOOKS]; + unsigned int underflow[NF_ARP_NUMHOOKS]; + void *entries[NR_CPUS]; +}; + +static LIST_HEAD(arpt_target); +static LIST_HEAD(arpt_tables); +#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) +#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) + static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, char *hdr_addr, int len) { @@ -205,9 +223,9 @@ static inline int arp_checkentry(const struct arpt_arp *arp) } static unsigned int arpt_error(struct sk_buff **pskb, + unsigned int hooknum, const struct net_device *in, const struct net_device *out, - unsigned int hooknum, const void *targinfo, void *userinfo) { @@ -236,7 +254,6 @@ unsigned int arpt_do_table(struct sk_buff **pskb, struct arpt_entry *e, *back; const char *indev, *outdev; void *table_base; - struct xt_table_info *private = table->private; /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) + @@ -248,9 +265,9 @@ unsigned int arpt_do_table(struct sk_buff **pskb, outdev = out ? out->name : nulldevname; read_lock_bh(&table->lock); - table_base = (void *)private->entries[smp_processor_id()]; - e = get_entry(table_base, private->hook_entry[hook]); - back = get_entry(table_base, private->underflow[hook]); + table_base = (void *)table->private->entries[smp_processor_id()]; + e = get_entry(table_base, table->private->hook_entry[hook]); + back = get_entry(table_base, table->private->underflow[hook]); arp = (*pskb)->nh.arph; do { @@ -298,8 +315,8 @@ unsigned int arpt_do_table(struct sk_buff **pskb, * abs. verdicts */ verdict = t->u.kernel.target->target(pskb, - in, out, hook, + in, out, t->data, userdata); @@ -324,6 +341,106 @@ unsigned int arpt_do_table(struct sk_buff **pskb, return verdict; } +/* + * These are weird, but module loading must not be done with mutex + * held (since they will register), and we have to have a single + * function to use try_then_request_module(). + */ + +/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ +static inline struct arpt_table *find_table_lock(const char *name) +{ + struct arpt_table *t; + + if (down_interruptible(&arpt_mutex) != 0) + return ERR_PTR(-EINTR); + + list_for_each_entry(t, &arpt_tables, list) + if (strcmp(t->name, name) == 0 && try_module_get(t->me)) + return t; + up(&arpt_mutex); + return NULL; +} + + +/* Find target, grabs ref. Returns ERR_PTR() on error. */ +static inline struct arpt_target *find_target(const char *name, u8 revision) +{ + struct arpt_target *t; + int err = 0; + + if (down_interruptible(&arpt_mutex) != 0) + return ERR_PTR(-EINTR); + + list_for_each_entry(t, &arpt_target, list) { + if (strcmp(t->name, name) == 0) { + if (t->revision == revision) { + if (try_module_get(t->me)) { + up(&arpt_mutex); + return t; + } + } else + err = -EPROTOTYPE; /* Found something. */ + } + } + up(&arpt_mutex); + return ERR_PTR(err); +} + +struct arpt_target *arpt_find_target(const char *name, u8 revision) +{ + struct arpt_target *target; + + target = try_then_request_module(find_target(name, revision), + "arpt_%s", name); + if (IS_ERR(target) || !target) + return NULL; + return target; +} + +static int target_revfn(const char *name, u8 revision, int *bestp) +{ + struct arpt_target *t; + int have_rev = 0; + + list_for_each_entry(t, &arpt_target, list) { + if (strcmp(t->name, name) == 0) { + if (t->revision > *bestp) + *bestp = t->revision; + if (t->revision == revision) + have_rev =1; + } + } + return have_rev; +} + +/* Returns true or false (if no such extension at all) */ +static inline int find_revision(const char *name, u8 revision, + int (*revfn)(const char *, u8, int *), + int *err) +{ + int have_rev, best = -1; + + if (down_interruptible(&arpt_mutex) != 0) { + *err = -EINTR; + return 1; + } + have_rev = revfn(name, revision, &best); + up(&arpt_mutex); + + /* Nothing at all? Return 0 to try loading module. */ + if (best == -1) { + *err = -ENOENT; + return 0; + } + + *err = best; + if (!have_rev) + *err = -EPROTONOSUPPORT; + return 1; +} + + /* All zeroes == unconditional rule. */ static inline int unconditional(const struct arpt_arp *arp) { @@ -339,7 +456,7 @@ static inline int unconditional(const struct arpt_arp *arp) /* Figures out from what hook each rule can be called: returns 0 if * there are loops. Puts hook bitmask in comefrom. */ -static int mark_source_chains(struct xt_table_info *newinfo, +static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int valid_hooks, void *entry0) { unsigned int hook; @@ -470,8 +587,8 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i } t = arpt_get_target(e); - target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, - t->u.user.revision), + target = try_then_request_module(find_target(t->u.user.name, + t->u.user.revision), "arpt_%s", t->u.user.name); if (IS_ERR(target) || !target) { duprintf("check_entry: `%s' not found\n", t->u.user.name); @@ -505,7 +622,7 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i } static inline int check_entry_size_and_hooks(struct arpt_entry *e, - struct xt_table_info *newinfo, + struct arpt_table_info *newinfo, unsigned char *base, unsigned char *limit, const unsigned int *hook_entries, @@ -539,7 +656,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, < 0 (not ARPT_RETURN). --RR */ /* Clear counters and comefrom */ - e->counters = ((struct xt_counters) { 0, 0 }); + e->counters = ((struct arpt_counters) { 0, 0 }); e->comefrom = 0; (*i)++; @@ -566,7 +683,7 @@ static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) */ static int translate_table(const char *name, unsigned int valid_hooks, - struct xt_table_info *newinfo, + struct arpt_table_info *newinfo, void *entry0, unsigned int size, unsigned int number, @@ -647,9 +764,34 @@ static int translate_table(const char *name, return ret; } +static struct arpt_table_info *replace_table(struct arpt_table *table, + unsigned int num_counters, + struct arpt_table_info *newinfo, + int *error) +{ + struct arpt_table_info *oldinfo; + + /* Do the substitution. */ + write_lock_bh(&table->lock); + /* Check inside lock: is the old number correct? */ + if (num_counters != table->private->number) { + duprintf("num_counters != table->private->number (%u/%u)\n", + num_counters, table->private->number); + write_unlock_bh(&table->lock); + *error = -EAGAIN; + return NULL; + } + oldinfo = table->private; + table->private = newinfo; + newinfo->initial_entries = oldinfo->initial_entries; + write_unlock_bh(&table->lock); + + return oldinfo; +} + /* Gets counters. */ static inline int add_entry_to_counter(const struct arpt_entry *e, - struct xt_counters total[], + struct arpt_counters total[], unsigned int *i) { ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); @@ -659,7 +801,7 @@ static inline int add_entry_to_counter(const struct arpt_entry *e, } static inline int set_entry_to_counter(const struct arpt_entry *e, - struct xt_counters total[], + struct arpt_counters total[], unsigned int *i) { SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); @@ -668,8 +810,8 @@ static inline int set_entry_to_counter(const struct arpt_entry *e, return 0; } -static void get_counters(const struct xt_table_info *t, - struct xt_counters counters[]) +static void get_counters(const struct arpt_table_info *t, + struct arpt_counters counters[]) { unsigned int cpu; unsigned int i; @@ -707,8 +849,7 @@ static int copy_entries_to_user(unsigned int total_size, { unsigned int off, num, countersize; struct arpt_entry *e; - struct xt_counters *counters; - struct xt_table_info *private = table->private; + struct arpt_counters *counters; int ret = 0; void *loc_cpu_entry; @@ -716,18 +857,18 @@ static int copy_entries_to_user(unsigned int total_size, * (other than comefrom, which userspace doesn't care * about). */ - countersize = sizeof(struct xt_counters) * private->number; - counters = vmalloc_node(countersize, numa_node_id()); + countersize = sizeof(struct arpt_counters) * table->private->number; + counters = vmalloc(countersize); if (counters == NULL) return -ENOMEM; /* First, sum counters... */ write_lock_bh(&table->lock); - get_counters(private, counters); + get_counters(table->private, counters); write_unlock_bh(&table->lock); - loc_cpu_entry = private->entries[raw_smp_processor_id()]; + loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; /* ... then copy entire thing ... */ if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { ret = -EFAULT; @@ -770,34 +911,75 @@ static int get_entries(const struct arpt_get_entries *entries, int ret; struct arpt_table *t; - t = xt_find_table_lock(NF_ARP, entries->name); + t = find_table_lock(entries->name); if (t || !IS_ERR(t)) { - struct xt_table_info *private = t->private; duprintf("t->private->number = %u\n", - private->number); - if (entries->size == private->size) - ret = copy_entries_to_user(private->size, + t->private->number); + if (entries->size == t->private->size) + ret = copy_entries_to_user(t->private->size, t, uptr->entrytable); else { duprintf("get_entries: I've got %u not %u!\n", - private->size, entries->size); + t->private->size, + entries->size); ret = -EINVAL; } module_put(t->me); - xt_table_unlock(t); + up(&arpt_mutex); } else ret = t ? PTR_ERR(t) : -ENOENT; return ret; } +static void free_table_info(struct arpt_table_info *info) +{ + int cpu; + for_each_cpu(cpu) { + if (info->size <= PAGE_SIZE) + kfree(info->entries[cpu]); + else + vfree(info->entries[cpu]); + } + kfree(info); +} + +static struct arpt_table_info *alloc_table_info(unsigned int size) +{ + struct arpt_table_info *newinfo; + int cpu; + + newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL); + if (!newinfo) + return NULL; + + newinfo->size = size; + + for_each_cpu(cpu) { + if (size <= PAGE_SIZE) + newinfo->entries[cpu] = kmalloc_node(size, + GFP_KERNEL, + cpu_to_node(cpu)); + else + newinfo->entries[cpu] = vmalloc_node(size, + cpu_to_node(cpu)); + + if (newinfo->entries[cpu] == NULL) { + free_table_info(newinfo); + return NULL; + } + } + + return newinfo; +} + static int do_replace(void __user *user, unsigned int len) { int ret; struct arpt_replace tmp; struct arpt_table *t; - struct xt_table_info *newinfo, *oldinfo; - struct xt_counters *counters; + struct arpt_table_info *newinfo, *oldinfo; + struct arpt_counters *counters; void *loc_cpu_entry, *loc_cpu_old_entry; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) @@ -807,7 +989,11 @@ static int do_replace(void __user *user, unsigned int len) if (len != sizeof(tmp) + tmp.size) return -ENOPROTOOPT; - newinfo = xt_alloc_table_info(tmp.size); + /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ + if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) + return -ENOMEM; + + newinfo = alloc_table_info(tmp.size); if (!newinfo) return -ENOMEM; @@ -819,7 +1005,7 @@ static int do_replace(void __user *user, unsigned int len) goto free_newinfo; } - counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); + counters = vmalloc(tmp.num_counters * sizeof(struct arpt_counters)); if (!counters) { ret = -ENOMEM; goto free_newinfo; @@ -833,7 +1019,7 @@ static int do_replace(void __user *user, unsigned int len) duprintf("arp_tables: Translated table\n"); - t = try_then_request_module(xt_find_table_lock(NF_ARP, tmp.name), + t = try_then_request_module(find_table_lock(tmp.name), "arptable_%s", tmp.name); if (!t || IS_ERR(t)) { ret = t ? PTR_ERR(t) : -ENOENT; @@ -848,7 +1034,7 @@ static int do_replace(void __user *user, unsigned int len) goto put_module; } - oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); + oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); if (!oldinfo) goto put_module; @@ -868,23 +1054,23 @@ static int do_replace(void __user *user, unsigned int len) loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); - xt_free_table_info(oldinfo); + free_table_info(oldinfo); if (copy_to_user(tmp.counters, counters, - sizeof(struct xt_counters) * tmp.num_counters) != 0) + sizeof(struct arpt_counters) * tmp.num_counters) != 0) ret = -EFAULT; vfree(counters); - xt_table_unlock(t); + up(&arpt_mutex); return ret; put_module: module_put(t->me); - xt_table_unlock(t); + up(&arpt_mutex); free_newinfo_counters_untrans: ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); free_newinfo_counters: vfree(counters); free_newinfo: - xt_free_table_info(newinfo); + free_table_info(newinfo); return ret; } @@ -892,7 +1078,7 @@ static int do_replace(void __user *user, unsigned int len) * and everything is OK. */ static inline int add_counter_to_entry(struct arpt_entry *e, - const struct xt_counters addme[], + const struct arpt_counters addme[], unsigned int *i) { @@ -905,16 +1091,15 @@ static inline int add_counter_to_entry(struct arpt_entry *e, static int do_add_counters(void __user *user, unsigned int len) { unsigned int i; - struct xt_counters_info tmp, *paddc; + struct arpt_counters_info tmp, *paddc; struct arpt_table *t; - struct xt_table_info *private; int ret = 0; void *loc_cpu_entry; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) return -EFAULT; - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) + if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct arpt_counters)) return -EINVAL; paddc = vmalloc(len); @@ -926,30 +1111,29 @@ static int do_add_counters(void __user *user, unsigned int len) goto free; } - t = xt_find_table_lock(NF_ARP, tmp.name); + t = find_table_lock(tmp.name); if (!t || IS_ERR(t)) { ret = t ? PTR_ERR(t) : -ENOENT; goto free; } write_lock_bh(&t->lock); - private = t->private; - if (private->number != paddc->num_counters) { + if (t->private->number != paddc->num_counters) { ret = -EINVAL; goto unlock_up_free; } i = 0; /* Choose the copy that is on our node */ - loc_cpu_entry = private->entries[smp_processor_id()]; + loc_cpu_entry = t->private->entries[smp_processor_id()]; ARPT_ENTRY_ITERATE(loc_cpu_entry, - private->size, + t->private->size, add_counter_to_entry, paddc->counters, &i); unlock_up_free: write_unlock_bh(&t->lock); - xt_table_unlock(t); + up(&arpt_mutex); module_put(t->me); free: vfree(paddc); @@ -1006,26 +1190,25 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len } name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; - t = try_then_request_module(xt_find_table_lock(NF_ARP, name), + t = try_then_request_module(find_table_lock(name), "arptable_%s", name); if (t && !IS_ERR(t)) { struct arpt_getinfo info; - struct xt_table_info *private = t->private; info.valid_hooks = t->valid_hooks; - memcpy(info.hook_entry, private->hook_entry, + memcpy(info.hook_entry, t->private->hook_entry, sizeof(info.hook_entry)); - memcpy(info.underflow, private->underflow, + memcpy(info.underflow, t->private->underflow, sizeof(info.underflow)); - info.num_entries = private->number; - info.size = private->size; + info.num_entries = t->private->number; + info.size = t->private->size; strcpy(info.name, name); if (copy_to_user(user, &info, *len) != 0) ret = -EFAULT; else ret = 0; - xt_table_unlock(t); + up(&arpt_mutex); module_put(t->me); } else ret = t ? PTR_ERR(t) : -ENOENT; @@ -1050,7 +1233,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len } case ARPT_SO_GET_REVISION_TARGET: { - struct xt_get_revision rev; + struct arpt_get_revision rev; if (*len != sizeof(rev)) { ret = -EINVAL; @@ -1061,8 +1244,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len break; } - try_then_request_module(xt_find_revision(NF_ARP, rev.name, - rev.revision, 1, &ret), + try_then_request_module(find_revision(rev.name, rev.revision, + target_revfn, &ret), "arpt_%s", rev.name); break; } @@ -1075,16 +1258,38 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len return ret; } +/* Registration hooks for targets. */ +int arpt_register_target(struct arpt_target *target) +{ + int ret; + + ret = down_interruptible(&arpt_mutex); + if (ret != 0) + return ret; + + list_add(&target->list, &arpt_target); + up(&arpt_mutex); + + return ret; +} + +void arpt_unregister_target(struct arpt_target *target) +{ + down(&arpt_mutex); + LIST_DELETE(&arpt_target, target); + up(&arpt_mutex); +} + int arpt_register_table(struct arpt_table *table, const struct arpt_replace *repl) { int ret; - struct xt_table_info *newinfo; - static struct xt_table_info bootstrap + struct arpt_table_info *newinfo; + static struct arpt_table_info bootstrap = { 0, 0, 0, { 0 }, { 0 }, { } }; void *loc_cpu_entry; - newinfo = xt_alloc_table_info(repl->size); + newinfo = alloc_table_info(repl->size); if (!newinfo) { ret = -ENOMEM; return ret; @@ -1099,33 +1304,60 @@ int arpt_register_table(struct arpt_table *table, repl->num_entries, repl->hook_entry, repl->underflow); - duprintf("arpt_register_table: translate table gives %d\n", ret); if (ret != 0) { - xt_free_table_info(newinfo); + free_table_info(newinfo); return ret; } - if (xt_register_table(table, &bootstrap, newinfo) != 0) { - xt_free_table_info(newinfo); + ret = down_interruptible(&arpt_mutex); + if (ret != 0) { + free_table_info(newinfo); return ret; } - return 0; + /* Don't autoload: we'd eat our tail... */ + if (list_named_find(&arpt_tables, table->name)) { + ret = -EEXIST; + goto free_unlock; + } + + /* Simplifies replace_table code. */ + table->private = &bootstrap; + if (!replace_table(table, 0, newinfo, &ret)) + goto free_unlock; + + duprintf("table->private->number = %u\n", + table->private->number); + + /* save number of initial entries */ + table->private->initial_entries = table->private->number; + + rwlock_init(&table->lock); + list_prepend(&arpt_tables, table); + + unlock: + up(&arpt_mutex); + return ret; + + free_unlock: + free_table_info(newinfo); + goto unlock; } void arpt_unregister_table(struct arpt_table *table) { - struct xt_table_info *private; void *loc_cpu_entry; - private = xt_unregister_table(table); + down(&arpt_mutex); + LIST_DELETE(&arpt_tables, table); + up(&arpt_mutex); /* Decrease module usage counts and free resources */ - loc_cpu_entry = private->entries[raw_smp_processor_id()]; - ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, + loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; + ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, cleanup_entry, NULL); - xt_free_table_info(private); + free_table_info(table->private); } /* The built-in targets: standard (NULL) and error. */ @@ -1148,15 +1380,52 @@ static struct nf_sockopt_ops arpt_sockopts = { .get = do_arpt_get_ctl, }; +#ifdef CONFIG_PROC_FS +static inline int print_name(const struct arpt_table *t, + off_t start_offset, char *buffer, int length, + off_t *pos, unsigned int *count) +{ + if ((*count)++ >= start_offset) { + unsigned int namelen; + + namelen = sprintf(buffer + *pos, "%s\n", t->name); + if (*pos + namelen > length) { + /* Stop iterating */ + return 1; + } + *pos += namelen; + } + return 0; +} + +static int arpt_get_tables(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&arpt_mutex) != 0) + return 0; + + LIST_FIND(&arpt_tables, print_name, struct arpt_table *, + offset, buffer, length, &pos, &count); + + up(&arpt_mutex); + + /* `start' hack - see fs/proc/generic.c line ~105 */ + *start=(char *)((unsigned long)count-offset); + return pos; +} +#endif /*CONFIG_PROC_FS*/ + static int __init init(void) { int ret; - xt_proto_init(NF_ARP); - /* Noone else will be downing sem now, so we won't sleep */ - xt_register_target(NF_ARP, &arpt_standard_target); - xt_register_target(NF_ARP, &arpt_error_target); + down(&arpt_mutex); + list_append(&arpt_target, &arpt_standard_target); + list_append(&arpt_target, &arpt_error_target); + up(&arpt_mutex); /* Register setsockopt */ ret = nf_register_sockopt(&arpt_sockopts); @@ -1165,6 +1434,19 @@ static int __init init(void) return ret; } +#ifdef CONFIG_PROC_FS + { + struct proc_dir_entry *proc; + + proc = proc_net_create("arp_tables_names", 0, arpt_get_tables); + if (!proc) { + nf_unregister_sockopt(&arpt_sockopts); + return -ENOMEM; + } + proc->owner = THIS_MODULE; + } +#endif + printk("arp_tables: (C) 2002 David S. Miller\n"); return 0; } @@ -1172,12 +1454,16 @@ static int __init init(void) static void __exit fini(void) { nf_unregister_sockopt(&arpt_sockopts); - xt_proto_fini(NF_ARP); +#ifdef CONFIG_PROC_FS + proc_net_remove("arp_tables_names"); +#endif } EXPORT_SYMBOL(arpt_register_table); EXPORT_SYMBOL(arpt_unregister_table); EXPORT_SYMBOL(arpt_do_table); +EXPORT_SYMBOL(arpt_register_target); +EXPORT_SYMBOL(arpt_unregister_target); module_init(init); module_exit(fini); diff --git a/trunk/net/ipv4/netfilter/arpt_mangle.c b/trunk/net/ipv4/netfilter/arpt_mangle.c index c97650a16a5b..3e592ec86482 100644 --- a/trunk/net/ipv4/netfilter/arpt_mangle.c +++ b/trunk/net/ipv4/netfilter/arpt_mangle.c @@ -8,9 +8,8 @@ MODULE_AUTHOR("Bart De Schuymer "); MODULE_DESCRIPTION("arptables arp payload mangle target"); static unsigned int -target(struct sk_buff **pskb, const struct net_device *in, - const struct net_device *out, unsigned int hooknum, const void *targinfo, - void *userinfo) +target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, + const struct net_device *out, const void *targinfo, void *userinfo) { const struct arpt_mangle *mangle = targinfo; struct arphdr *arp; @@ -65,7 +64,7 @@ target(struct sk_buff **pskb, const struct net_device *in, } static int -checkentry(const char *tablename, const void *e, void *targinfo, +checkentry(const char *tablename, const struct arpt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { const struct arpt_mangle *mangle = targinfo; diff --git a/trunk/net/ipv4/netfilter/arptable_filter.c b/trunk/net/ipv4/netfilter/arptable_filter.c index f6ab45f48681..0d759f5a4ef0 100644 --- a/trunk/net/ipv4/netfilter/arptable_filter.c +++ b/trunk/net/ipv4/netfilter/arptable_filter.c @@ -145,7 +145,6 @@ static struct arpt_table packet_filter = { .lock = RW_LOCK_UNLOCKED, .private = NULL, .me = THIS_MODULE, - .af = NF_ARP, }; /* The work comes in here from netfilter.c */ diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c b/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c index 833fcb4be5e7..9dec1293f67a 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -944,7 +944,7 @@ module_exit(fini); /* Some modules need us, but don't depend directly on any symbol. They should call this. */ -void need_conntrack(void) +void need_ip_conntrack(void) { } @@ -962,7 +962,7 @@ EXPORT_SYMBOL(ip_ct_get_tuple); EXPORT_SYMBOL(invert_tuplepr); EXPORT_SYMBOL(ip_conntrack_alter_reply); EXPORT_SYMBOL(ip_conntrack_destroyed); -EXPORT_SYMBOL(need_conntrack); +EXPORT_SYMBOL(need_ip_conntrack); EXPORT_SYMBOL(ip_conntrack_helper_register); EXPORT_SYMBOL(ip_conntrack_helper_unregister); EXPORT_SYMBOL(ip_ct_iterate_cleanup); diff --git a/trunk/net/ipv4/netfilter/ip_nat_rule.c b/trunk/net/ipv4/netfilter/ip_nat_rule.c index 1de86282d232..cb66b8bddeb3 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_rule.c +++ b/trunk/net/ipv4/netfilter/ip_nat_rule.c @@ -95,7 +95,6 @@ static struct ipt_table nat_table = { .valid_hooks = NAT_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, .me = THIS_MODULE, - .af = AF_INET, }; /* Source NAT */ @@ -169,7 +168,7 @@ static unsigned int ipt_dnat_target(struct sk_buff **pskb, } static int ipt_snat_checkentry(const char *tablename, - const void *entry, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) @@ -202,7 +201,7 @@ static int ipt_snat_checkentry(const char *tablename, } static int ipt_dnat_checkentry(const char *tablename, - const void *entry, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ip_nat_standalone.c b/trunk/net/ipv4/netfilter/ip_nat_standalone.c index ad438fb185b8..8b8a1f00bbf4 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_standalone.c +++ b/trunk/net/ipv4/netfilter/ip_nat_standalone.c @@ -364,7 +364,7 @@ static int init_or_cleanup(int init) { int ret = 0; - need_conntrack(); + need_ip_conntrack(); if (!init) goto cleanup; diff --git a/trunk/net/ipv4/netfilter/ip_tables.c b/trunk/net/ipv4/netfilter/ip_tables.c index 2371b2062c2d..877bc96d3336 100644 --- a/trunk/net/ipv4/netfilter/ip_tables.c +++ b/trunk/net/ipv4/netfilter/ip_tables.c @@ -2,7 +2,7 @@ * Packet matching code. * * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling - * Copyright (C) 2000-2005 Netfilter Core Team + * Copyright (C) 2000-2004 Netfilter Core Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -11,8 +11,6 @@ * 19 Jan 2002 Harald Welte * - increase module usage count as soon as we have rules inside * a table - * 08 Oct 2005 Harald Welte - * - Generalize into "x_tables" layer and "{ip,ip6,arp}_tables" */ #include #include @@ -22,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -30,7 +30,6 @@ #include #include -#include #include MODULE_LICENSE("GPL"); @@ -63,6 +62,14 @@ do { \ #else #define IP_NF_ASSERT(x) #endif +#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) + +static DECLARE_MUTEX(ipt_mutex); + +/* Must have mutex */ +#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) +#define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0) +#include #if 0 /* All the better to debug you with... */ @@ -79,6 +86,36 @@ do { \ Hence the start of any table is given by get_table() below. */ +/* The table itself */ +struct ipt_table_info +{ + /* Size per table */ + unsigned int size; + /* Number of entries: FIXME. --RR */ + unsigned int number; + /* Initial number of entries. Needed for module usage count */ + unsigned int initial_entries; + + /* Entry points and underflows */ + unsigned int hook_entry[NF_IP_NUMHOOKS]; + unsigned int underflow[NF_IP_NUMHOOKS]; + + /* ipt_entry tables: one per CPU */ + void *entries[NR_CPUS]; +}; + +static LIST_HEAD(ipt_target); +static LIST_HEAD(ipt_match); +static LIST_HEAD(ipt_tables); +#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) +#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) + +#if 0 +#define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) +#define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) +#define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) +#endif + /* Returns whether matches rule or not. */ static inline int ip_packet_match(const struct iphdr *ip, @@ -197,8 +234,7 @@ int do_match(struct ipt_entry_match *m, int *hotdrop) { /* Stop iteration if it doesn't match */ - if (!m->u.kernel.match->match(skb, in, out, m->data, offset, - skb->nh.iph->ihl*4, hotdrop)) + if (!m->u.kernel.match->match(skb, in, out, m->data, offset, hotdrop)) return 1; else return 0; @@ -229,7 +265,6 @@ ipt_do_table(struct sk_buff **pskb, const char *indev, *outdev; void *table_base; struct ipt_entry *e, *back; - struct xt_table_info *private = table->private; /* Initialization */ ip = (*pskb)->nh.iph; @@ -246,11 +281,24 @@ ipt_do_table(struct sk_buff **pskb, read_lock_bh(&table->lock); IP_NF_ASSERT(table->valid_hooks & (1 << hook)); - table_base = (void *)private->entries[smp_processor_id()]; - e = get_entry(table_base, private->hook_entry[hook]); + table_base = (void *)table->private->entries[smp_processor_id()]; + e = get_entry(table_base, table->private->hook_entry[hook]); + +#ifdef CONFIG_NETFILTER_DEBUG + /* Check noone else using our table */ + if (((struct ipt_entry *)table_base)->comefrom != 0xdead57ac + && ((struct ipt_entry *)table_base)->comefrom != 0xeeeeeeec) { + printk("ASSERT: CPU #%u, %s comefrom(%p) = %X\n", + smp_processor_id(), + table->name, + &((struct ipt_entry *)table_base)->comefrom, + ((struct ipt_entry *)table_base)->comefrom); + } + ((struct ipt_entry *)table_base)->comefrom = 0x57acc001; +#endif /* For return from builtin chain */ - back = get_entry(table_base, private->underflow[hook]); + back = get_entry(table_base, table->private->underflow[hook]); do { IP_NF_ASSERT(e); @@ -336,6 +384,9 @@ ipt_do_table(struct sk_buff **pskb, } } while (!hotdrop); +#ifdef CONFIG_NETFILTER_DEBUG + ((struct ipt_entry *)table_base)->comefrom = 0xdead57ac; +#endif read_unlock_bh(&table->lock); #ifdef DEBUG_ALLOW_ALL @@ -347,6 +398,145 @@ ipt_do_table(struct sk_buff **pskb, #endif } +/* + * These are weird, but module loading must not be done with mutex + * held (since they will register), and we have to have a single + * function to use try_then_request_module(). + */ + +/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ +static inline struct ipt_table *find_table_lock(const char *name) +{ + struct ipt_table *t; + + if (down_interruptible(&ipt_mutex) != 0) + return ERR_PTR(-EINTR); + + list_for_each_entry(t, &ipt_tables, list) + if (strcmp(t->name, name) == 0 && try_module_get(t->me)) + return t; + up(&ipt_mutex); + return NULL; +} + +/* Find match, grabs ref. Returns ERR_PTR() on error. */ +static inline struct ipt_match *find_match(const char *name, u8 revision) +{ + struct ipt_match *m; + int err = 0; + + if (down_interruptible(&ipt_mutex) != 0) + return ERR_PTR(-EINTR); + + list_for_each_entry(m, &ipt_match, list) { + if (strcmp(m->name, name) == 0) { + if (m->revision == revision) { + if (try_module_get(m->me)) { + up(&ipt_mutex); + return m; + } + } else + err = -EPROTOTYPE; /* Found something. */ + } + } + up(&ipt_mutex); + return ERR_PTR(err); +} + +/* Find target, grabs ref. Returns ERR_PTR() on error. */ +static inline struct ipt_target *find_target(const char *name, u8 revision) +{ + struct ipt_target *t; + int err = 0; + + if (down_interruptible(&ipt_mutex) != 0) + return ERR_PTR(-EINTR); + + list_for_each_entry(t, &ipt_target, list) { + if (strcmp(t->name, name) == 0) { + if (t->revision == revision) { + if (try_module_get(t->me)) { + up(&ipt_mutex); + return t; + } + } else + err = -EPROTOTYPE; /* Found something. */ + } + } + up(&ipt_mutex); + return ERR_PTR(err); +} + +struct ipt_target *ipt_find_target(const char *name, u8 revision) +{ + struct ipt_target *target; + + target = try_then_request_module(find_target(name, revision), + "ipt_%s", name); + if (IS_ERR(target) || !target) + return NULL; + return target; +} + +static int match_revfn(const char *name, u8 revision, int *bestp) +{ + struct ipt_match *m; + int have_rev = 0; + + list_for_each_entry(m, &ipt_match, list) { + if (strcmp(m->name, name) == 0) { + if (m->revision > *bestp) + *bestp = m->revision; + if (m->revision == revision) + have_rev = 1; + } + } + return have_rev; +} + +static int target_revfn(const char *name, u8 revision, int *bestp) +{ + struct ipt_target *t; + int have_rev = 0; + + list_for_each_entry(t, &ipt_target, list) { + if (strcmp(t->name, name) == 0) { + if (t->revision > *bestp) + *bestp = t->revision; + if (t->revision == revision) + have_rev = 1; + } + } + return have_rev; +} + +/* Returns true or false (if no such extension at all) */ +static inline int find_revision(const char *name, u8 revision, + int (*revfn)(const char *, u8, int *), + int *err) +{ + int have_rev, best = -1; + + if (down_interruptible(&ipt_mutex) != 0) { + *err = -EINTR; + return 1; + } + have_rev = revfn(name, revision, &best); + up(&ipt_mutex); + + /* Nothing at all? Return 0 to try loading module. */ + if (best == -1) { + *err = -ENOENT; + return 0; + } + + *err = best; + if (!have_rev) + *err = -EPROTONOSUPPORT; + return 1; +} + + /* All zeroes == unconditional rule. */ static inline int unconditional(const struct ipt_ip *ip) @@ -363,7 +553,7 @@ unconditional(const struct ipt_ip *ip) /* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int -mark_source_chains(struct xt_table_info *newinfo, +mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks, void *entry0) { unsigned int hook; @@ -509,7 +699,7 @@ check_match(struct ipt_entry_match *m, { struct ipt_match *match; - match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, + match = try_then_request_module(find_match(m->u.user.name, m->u.user.revision), "ipt_%s", m->u.user.name); if (IS_ERR(match) || !match) { @@ -554,8 +744,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, goto cleanup_matches; t = ipt_get_target(e); - target = try_then_request_module(xt_find_target(AF_INET, - t->u.user.name, + target = try_then_request_module(find_target(t->u.user.name, t->u.user.revision), "ipt_%s", t->u.user.name); if (IS_ERR(target) || !target) { @@ -592,7 +781,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, static inline int check_entry_size_and_hooks(struct ipt_entry *e, - struct xt_table_info *newinfo, + struct ipt_table_info *newinfo, unsigned char *base, unsigned char *limit, const unsigned int *hook_entries, @@ -626,7 +815,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, < 0 (not IPT_RETURN). --RR */ /* Clear counters and comefrom */ - e->counters = ((struct xt_counters) { 0, 0 }); + e->counters = ((struct ipt_counters) { 0, 0 }); e->comefrom = 0; (*i)++; @@ -656,7 +845,7 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i) static int translate_table(const char *name, unsigned int valid_hooks, - struct xt_table_info *newinfo, + struct ipt_table_info *newinfo, void *entry0, unsigned int size, unsigned int number, @@ -733,10 +922,48 @@ translate_table(const char *name, return ret; } +static struct ipt_table_info * +replace_table(struct ipt_table *table, + unsigned int num_counters, + struct ipt_table_info *newinfo, + int *error) +{ + struct ipt_table_info *oldinfo; + +#ifdef CONFIG_NETFILTER_DEBUG + { + int cpu; + + for_each_cpu(cpu) { + struct ipt_entry *table_base = newinfo->entries[cpu]; + if (table_base) + table_base->comefrom = 0xdead57ac; + } + } +#endif + + /* Do the substitution. */ + write_lock_bh(&table->lock); + /* Check inside lock: is the old number correct? */ + if (num_counters != table->private->number) { + duprintf("num_counters != table->private->number (%u/%u)\n", + num_counters, table->private->number); + write_unlock_bh(&table->lock); + *error = -EAGAIN; + return NULL; + } + oldinfo = table->private; + table->private = newinfo; + newinfo->initial_entries = oldinfo->initial_entries; + write_unlock_bh(&table->lock); + + return oldinfo; +} + /* Gets counters. */ static inline int add_entry_to_counter(const struct ipt_entry *e, - struct xt_counters total[], + struct ipt_counters total[], unsigned int *i) { ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); @@ -757,8 +984,8 @@ set_entry_to_counter(const struct ipt_entry *e, } static void -get_counters(const struct xt_table_info *t, - struct xt_counters counters[]) +get_counters(const struct ipt_table_info *t, + struct ipt_counters counters[]) { unsigned int cpu; unsigned int i; @@ -797,15 +1024,14 @@ copy_entries_to_user(unsigned int total_size, { unsigned int off, num, countersize; struct ipt_entry *e; - struct xt_counters *counters; - struct xt_table_info *private = table->private; + struct ipt_counters *counters; int ret = 0; void *loc_cpu_entry; /* We need atomic snapshot of counters: rest doesn't change (other than comefrom, which userspace doesn't care about). */ - countersize = sizeof(struct xt_counters) * private->number; + countersize = sizeof(struct ipt_counters) * table->private->number; counters = vmalloc_node(countersize, numa_node_id()); if (counters == NULL) @@ -813,14 +1039,14 @@ copy_entries_to_user(unsigned int total_size, /* First, sum counters... */ write_lock_bh(&table->lock); - get_counters(private, counters); + get_counters(table->private, counters); write_unlock_bh(&table->lock); /* choose the copy that is on our node/cpu, ... * This choice is lazy (because current thread is * allowed to migrate to another cpu) */ - loc_cpu_entry = private->entries[raw_smp_processor_id()]; + loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; /* ... then copy entire thing ... */ if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { ret = -EFAULT; @@ -882,36 +1108,74 @@ get_entries(const struct ipt_get_entries *entries, int ret; struct ipt_table *t; - t = xt_find_table_lock(AF_INET, entries->name); + t = find_table_lock(entries->name); if (t && !IS_ERR(t)) { - struct xt_table_info *private = t->private; duprintf("t->private->number = %u\n", - private->number); - if (entries->size == private->size) - ret = copy_entries_to_user(private->size, + t->private->number); + if (entries->size == t->private->size) + ret = copy_entries_to_user(t->private->size, t, uptr->entrytable); else { duprintf("get_entries: I've got %u not %u!\n", - private->size, + t->private->size, entries->size); ret = -EINVAL; } module_put(t->me); - xt_table_unlock(t); + up(&ipt_mutex); } else ret = t ? PTR_ERR(t) : -ENOENT; return ret; } +static void free_table_info(struct ipt_table_info *info) +{ + int cpu; + for_each_cpu(cpu) { + if (info->size <= PAGE_SIZE) + kfree(info->entries[cpu]); + else + vfree(info->entries[cpu]); + } + kfree(info); +} + +static struct ipt_table_info *alloc_table_info(unsigned int size) +{ + struct ipt_table_info *newinfo; + int cpu; + + newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL); + if (!newinfo) + return NULL; + + newinfo->size = size; + + for_each_cpu(cpu) { + if (size <= PAGE_SIZE) + newinfo->entries[cpu] = kmalloc_node(size, + GFP_KERNEL, + cpu_to_node(cpu)); + else + newinfo->entries[cpu] = vmalloc_node(size, cpu_to_node(cpu)); + if (newinfo->entries[cpu] == 0) { + free_table_info(newinfo); + return NULL; + } + } + + return newinfo; +} + static int do_replace(void __user *user, unsigned int len) { int ret; struct ipt_replace tmp; struct ipt_table *t; - struct xt_table_info *newinfo, *oldinfo; - struct xt_counters *counters; + struct ipt_table_info *newinfo, *oldinfo; + struct ipt_counters *counters; void *loc_cpu_entry, *loc_cpu_old_entry; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) @@ -921,7 +1185,11 @@ do_replace(void __user *user, unsigned int len) if (len != sizeof(tmp) + tmp.size) return -ENOPROTOOPT; - newinfo = xt_alloc_table_info(tmp.size); + /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ + if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) + return -ENOMEM; + + newinfo = alloc_table_info(tmp.size); if (!newinfo) return -ENOMEM; @@ -933,7 +1201,7 @@ do_replace(void __user *user, unsigned int len) goto free_newinfo; } - counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); + counters = vmalloc(tmp.num_counters * sizeof(struct ipt_counters)); if (!counters) { ret = -ENOMEM; goto free_newinfo; @@ -947,7 +1215,7 @@ do_replace(void __user *user, unsigned int len) duprintf("ip_tables: Translated table\n"); - t = try_then_request_module(xt_find_table_lock(AF_INET, tmp.name), + t = try_then_request_module(find_table_lock(tmp.name), "iptable_%s", tmp.name); if (!t || IS_ERR(t)) { ret = t ? PTR_ERR(t) : -ENOENT; @@ -962,7 +1230,7 @@ do_replace(void __user *user, unsigned int len) goto put_module; } - oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); + oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); if (!oldinfo) goto put_module; @@ -981,23 +1249,23 @@ do_replace(void __user *user, unsigned int len) /* Decrease module usage counts and free resource */ loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); - xt_free_table_info(oldinfo); + free_table_info(oldinfo); if (copy_to_user(tmp.counters, counters, - sizeof(struct xt_counters) * tmp.num_counters) != 0) + sizeof(struct ipt_counters) * tmp.num_counters) != 0) ret = -EFAULT; vfree(counters); - xt_table_unlock(t); + up(&ipt_mutex); return ret; put_module: module_put(t->me); - xt_table_unlock(t); + up(&ipt_mutex); free_newinfo_counters_untrans: IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); free_newinfo_counters: vfree(counters); free_newinfo: - xt_free_table_info(newinfo); + free_table_info(newinfo); return ret; } @@ -1005,7 +1273,7 @@ do_replace(void __user *user, unsigned int len) * and everything is OK. */ static inline int add_counter_to_entry(struct ipt_entry *e, - const struct xt_counters addme[], + const struct ipt_counters addme[], unsigned int *i) { #if 0 @@ -1027,16 +1295,15 @@ static int do_add_counters(void __user *user, unsigned int len) { unsigned int i; - struct xt_counters_info tmp, *paddc; + struct ipt_counters_info tmp, *paddc; struct ipt_table *t; - struct xt_table_info *private; int ret = 0; void *loc_cpu_entry; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) return -EFAULT; - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) + if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters)) return -EINVAL; paddc = vmalloc_node(len, numa_node_id()); @@ -1048,30 +1315,29 @@ do_add_counters(void __user *user, unsigned int len) goto free; } - t = xt_find_table_lock(AF_INET, tmp.name); + t = find_table_lock(tmp.name); if (!t || IS_ERR(t)) { ret = t ? PTR_ERR(t) : -ENOENT; goto free; } write_lock_bh(&t->lock); - private = t->private; - if (private->number != paddc->num_counters) { + if (t->private->number != paddc->num_counters) { ret = -EINVAL; goto unlock_up_free; } i = 0; /* Choose the copy that is on our node */ - loc_cpu_entry = private->entries[raw_smp_processor_id()]; + loc_cpu_entry = t->private->entries[raw_smp_processor_id()]; IPT_ENTRY_ITERATE(loc_cpu_entry, - private->size, + t->private->size, add_counter_to_entry, paddc->counters, &i); unlock_up_free: write_unlock_bh(&t->lock); - xt_table_unlock(t); + up(&ipt_mutex); module_put(t->me); free: vfree(paddc); @@ -1130,26 +1396,25 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) } name[IPT_TABLE_MAXNAMELEN-1] = '\0'; - t = try_then_request_module(xt_find_table_lock(AF_INET, name), + t = try_then_request_module(find_table_lock(name), "iptable_%s", name); if (t && !IS_ERR(t)) { struct ipt_getinfo info; - struct xt_table_info *private = t->private; info.valid_hooks = t->valid_hooks; - memcpy(info.hook_entry, private->hook_entry, + memcpy(info.hook_entry, t->private->hook_entry, sizeof(info.hook_entry)); - memcpy(info.underflow, private->underflow, + memcpy(info.underflow, t->private->underflow, sizeof(info.underflow)); - info.num_entries = private->number; - info.size = private->size; + info.num_entries = t->private->number; + info.size = t->private->size; memcpy(info.name, name, sizeof(info.name)); if (copy_to_user(user, &info, *len) != 0) ret = -EFAULT; else ret = 0; - xt_table_unlock(t); + up(&ipt_mutex); module_put(t->me); } else ret = t ? PTR_ERR(t) : -ENOENT; @@ -1176,7 +1441,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) case IPT_SO_GET_REVISION_MATCH: case IPT_SO_GET_REVISION_TARGET: { struct ipt_get_revision rev; - int target; + int (*revfn)(const char *, u8, int *); if (*len != sizeof(rev)) { ret = -EINVAL; @@ -1188,13 +1453,12 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) } if (cmd == IPT_SO_GET_REVISION_TARGET) - target = 1; + revfn = target_revfn; else - target = 0; + revfn = match_revfn; - try_then_request_module(xt_find_revision(AF_INET, rev.name, - rev.revision, - target, &ret), + try_then_request_module(find_revision(rev.name, rev.revision, + revfn, &ret), "ipt_%s", rev.name); break; } @@ -1207,15 +1471,60 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) return ret; } -int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl) +/* Registration hooks for targets. */ +int +ipt_register_target(struct ipt_target *target) { int ret; - struct xt_table_info *newinfo; - static struct xt_table_info bootstrap + + ret = down_interruptible(&ipt_mutex); + if (ret != 0) + return ret; + list_add(&target->list, &ipt_target); + up(&ipt_mutex); + return ret; +} + +void +ipt_unregister_target(struct ipt_target *target) +{ + down(&ipt_mutex); + LIST_DELETE(&ipt_target, target); + up(&ipt_mutex); +} + +int +ipt_register_match(struct ipt_match *match) +{ + int ret; + + ret = down_interruptible(&ipt_mutex); + if (ret != 0) + return ret; + + list_add(&match->list, &ipt_match); + up(&ipt_mutex); + + return ret; +} + +void +ipt_unregister_match(struct ipt_match *match) +{ + down(&ipt_mutex); + LIST_DELETE(&ipt_match, match); + up(&ipt_mutex); +} + +int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl) +{ + int ret; + struct ipt_table_info *newinfo; + static struct ipt_table_info bootstrap = { 0, 0, 0, { 0 }, { 0 }, { } }; void *loc_cpu_entry; - newinfo = xt_alloc_table_info(repl->size); + newinfo = alloc_table_info(repl->size); if (!newinfo) return -ENOMEM; @@ -1231,29 +1540,246 @@ int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl) repl->hook_entry, repl->underflow); if (ret != 0) { - xt_free_table_info(newinfo); + free_table_info(newinfo); return ret; } - if (xt_register_table(table, &bootstrap, newinfo) != 0) { - xt_free_table_info(newinfo); + ret = down_interruptible(&ipt_mutex); + if (ret != 0) { + free_table_info(newinfo); return ret; } - return 0; + /* Don't autoload: we'd eat our tail... */ + if (list_named_find(&ipt_tables, table->name)) { + ret = -EEXIST; + goto free_unlock; + } + + /* Simplifies replace_table code. */ + table->private = &bootstrap; + if (!replace_table(table, 0, newinfo, &ret)) + goto free_unlock; + + duprintf("table->private->number = %u\n", + table->private->number); + + /* save number of initial entries */ + table->private->initial_entries = table->private->number; + + rwlock_init(&table->lock); + list_prepend(&ipt_tables, table); + + unlock: + up(&ipt_mutex); + return ret; + + free_unlock: + free_table_info(newinfo); + goto unlock; } void ipt_unregister_table(struct ipt_table *table) { - struct xt_table_info *private; void *loc_cpu_entry; - private = xt_unregister_table(table); + down(&ipt_mutex); + LIST_DELETE(&ipt_tables, table); + up(&ipt_mutex); /* Decrease module usage counts and free resources */ - loc_cpu_entry = private->entries[raw_smp_processor_id()]; - IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); - xt_free_table_info(private); + loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; + IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size, + cleanup_entry, NULL); + free_table_info(table->private); +} + +/* Returns 1 if the port is matched by the range, 0 otherwise */ +static inline int +port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) +{ + int ret; + + ret = (port >= min && port <= max) ^ invert; + return ret; +} + +static int +tcp_find_option(u_int8_t option, + const struct sk_buff *skb, + unsigned int optlen, + int invert, + int *hotdrop) +{ + /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ + u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; + unsigned int i; + + duprintf("tcp_match: finding option\n"); + + if (!optlen) + return invert; + + /* If we don't have the whole header, drop packet. */ + op = skb_header_pointer(skb, + skb->nh.iph->ihl*4 + sizeof(struct tcphdr), + optlen, _opt); + if (op == NULL) { + *hotdrop = 1; + return 0; + } + + for (i = 0; i < optlen; ) { + if (op[i] == option) return !invert; + if (op[i] < 2) i++; + else i += op[i+1]?:1; + } + + return invert; +} + +static int +tcp_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop) +{ + struct tcphdr _tcph, *th; + const struct ipt_tcp *tcpinfo = matchinfo; + + if (offset) { + /* To quote Alan: + + Don't allow a fragment of TCP 8 bytes in. Nobody normal + causes this. Its a cracker trying to break in by doing a + flag overwrite to pass the direction checks. + */ + if (offset == 1) { + duprintf("Dropping evil TCP offset=1 frag.\n"); + *hotdrop = 1; + } + /* Must not be a fragment. */ + return 0; + } + +#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) + + th = skb_header_pointer(skb, skb->nh.iph->ihl*4, + sizeof(_tcph), &_tcph); + if (th == NULL) { + /* We've been asked to examine this packet, and we + can't. Hence, no choice but to drop. */ + duprintf("Dropping evil TCP offset=0 tinygram.\n"); + *hotdrop = 1; + return 0; + } + + if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], + ntohs(th->source), + !!(tcpinfo->invflags & IPT_TCP_INV_SRCPT))) + return 0; + if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], + ntohs(th->dest), + !!(tcpinfo->invflags & IPT_TCP_INV_DSTPT))) + return 0; + if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) + == tcpinfo->flg_cmp, + IPT_TCP_INV_FLAGS)) + return 0; + if (tcpinfo->option) { + if (th->doff * 4 < sizeof(_tcph)) { + *hotdrop = 1; + return 0; + } + if (!tcp_find_option(tcpinfo->option, skb, + th->doff*4 - sizeof(_tcph), + tcpinfo->invflags & IPT_TCP_INV_OPTION, + hotdrop)) + return 0; + } + return 1; +} + +/* Called when user tries to insert an entry of this type. */ +static int +tcp_checkentry(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + const struct ipt_tcp *tcpinfo = matchinfo; + + /* Must specify proto == TCP, and no unknown invflags */ + return ip->proto == IPPROTO_TCP + && !(ip->invflags & IPT_INV_PROTO) + && matchsize == IPT_ALIGN(sizeof(struct ipt_tcp)) + && !(tcpinfo->invflags & ~IPT_TCP_INV_MASK); +} + +static int +udp_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop) +{ + struct udphdr _udph, *uh; + const struct ipt_udp *udpinfo = matchinfo; + + /* Must not be a fragment. */ + if (offset) + return 0; + + uh = skb_header_pointer(skb, skb->nh.iph->ihl*4, + sizeof(_udph), &_udph); + if (uh == NULL) { + /* We've been asked to examine this packet, and we + can't. Hence, no choice but to drop. */ + duprintf("Dropping evil UDP tinygram.\n"); + *hotdrop = 1; + return 0; + } + + return port_match(udpinfo->spts[0], udpinfo->spts[1], + ntohs(uh->source), + !!(udpinfo->invflags & IPT_UDP_INV_SRCPT)) + && port_match(udpinfo->dpts[0], udpinfo->dpts[1], + ntohs(uh->dest), + !!(udpinfo->invflags & IPT_UDP_INV_DSTPT)); +} + +/* Called when user tries to insert an entry of this type. */ +static int +udp_checkentry(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchinfosize, + unsigned int hook_mask) +{ + const struct ipt_udp *udpinfo = matchinfo; + + /* Must specify proto == UDP, and no unknown invflags */ + if (ip->proto != IPPROTO_UDP || (ip->invflags & IPT_INV_PROTO)) { + duprintf("ipt_udp: Protocol %u != %u\n", ip->proto, + IPPROTO_UDP); + return 0; + } + if (matchinfosize != IPT_ALIGN(sizeof(struct ipt_udp))) { + duprintf("ipt_udp: matchsize %u != %u\n", + matchinfosize, IPT_ALIGN(sizeof(struct ipt_udp))); + return 0; + } + if (udpinfo->invflags & ~IPT_UDP_INV_MASK) { + duprintf("ipt_udp: unknown flags %X\n", + udpinfo->invflags); + return 0; + } + + return 1; } /* Returns 1 if the type and code is matched by the range, 0 otherwise */ @@ -1272,7 +1798,6 @@ icmp_match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { struct icmphdr _icmph, *ic; @@ -1282,7 +1807,8 @@ icmp_match(const struct sk_buff *skb, if (offset) return 0; - ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); + ic = skb_header_pointer(skb, skb->nh.iph->ihl*4, + sizeof(_icmph), &_icmph); if (ic == NULL) { /* We've been asked to examine this packet, and we * can't. Hence, no choice but to drop. @@ -1302,12 +1828,11 @@ icmp_match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int icmp_checkentry(const char *tablename, - const void *info, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - const struct ipt_ip *ip = info; const struct ipt_icmp *icmpinfo = matchinfo; /* Must specify proto == ICMP, and no unknown invflags */ @@ -1337,22 +1862,123 @@ static struct nf_sockopt_ops ipt_sockopts = { .get = do_ipt_get_ctl, }; +static struct ipt_match tcp_matchstruct = { + .name = "tcp", + .match = &tcp_match, + .checkentry = &tcp_checkentry, +}; + +static struct ipt_match udp_matchstruct = { + .name = "udp", + .match = &udp_match, + .checkentry = &udp_checkentry, +}; + static struct ipt_match icmp_matchstruct = { .name = "icmp", .match = &icmp_match, .checkentry = &icmp_checkentry, }; +#ifdef CONFIG_PROC_FS +static inline int print_name(const char *i, + off_t start_offset, char *buffer, int length, + off_t *pos, unsigned int *count) +{ + if ((*count)++ >= start_offset) { + unsigned int namelen; + + namelen = sprintf(buffer + *pos, "%s\n", + i + sizeof(struct list_head)); + if (*pos + namelen > length) { + /* Stop iterating */ + return 1; + } + *pos += namelen; + } + return 0; +} + +static inline int print_target(const struct ipt_target *t, + off_t start_offset, char *buffer, int length, + off_t *pos, unsigned int *count) +{ + if (t == &ipt_standard_target || t == &ipt_error_target) + return 0; + return print_name((char *)t, start_offset, buffer, length, pos, count); +} + +static int ipt_get_tables(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ipt_mutex) != 0) + return 0; + + LIST_FIND(&ipt_tables, print_name, void *, + offset, buffer, length, &pos, &count); + + up(&ipt_mutex); + + /* `start' hack - see fs/proc/generic.c line ~105 */ + *start=(char *)((unsigned long)count-offset); + return pos; +} + +static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ipt_mutex) != 0) + return 0; + + LIST_FIND(&ipt_target, print_target, struct ipt_target *, + offset, buffer, length, &pos, &count); + + up(&ipt_mutex); + + *start = (char *)((unsigned long)count - offset); + return pos; +} + +static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ipt_mutex) != 0) + return 0; + + LIST_FIND(&ipt_match, print_name, void *, + offset, buffer, length, &pos, &count); + + up(&ipt_mutex); + + *start = (char *)((unsigned long)count - offset); + return pos; +} + +static const struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = +{ { "ip_tables_names", ipt_get_tables }, + { "ip_tables_targets", ipt_get_targets }, + { "ip_tables_matches", ipt_get_matches }, + { NULL, NULL} }; +#endif /*CONFIG_PROC_FS*/ + static int __init init(void) { int ret; - xt_proto_init(AF_INET); - /* Noone else will be downing sem now, so we won't sleep */ - xt_register_target(AF_INET, &ipt_standard_target); - xt_register_target(AF_INET, &ipt_error_target); - xt_register_match(AF_INET, &icmp_matchstruct); + down(&ipt_mutex); + list_append(&ipt_target, &ipt_standard_target); + list_append(&ipt_target, &ipt_error_target); + list_append(&ipt_match, &tcp_matchstruct); + list_append(&ipt_match, &udp_matchstruct); + list_append(&ipt_match, &icmp_matchstruct); + up(&ipt_mutex); /* Register setsockopt */ ret = nf_register_sockopt(&ipt_sockopts); @@ -1361,23 +1987,49 @@ static int __init init(void) return ret; } - printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n"); +#ifdef CONFIG_PROC_FS + { + struct proc_dir_entry *proc; + int i; + + for (i = 0; ipt_proc_entry[i].name; i++) { + proc = proc_net_create(ipt_proc_entry[i].name, 0, + ipt_proc_entry[i].get_info); + if (!proc) { + while (--i >= 0) + proc_net_remove(ipt_proc_entry[i].name); + nf_unregister_sockopt(&ipt_sockopts); + return -ENOMEM; + } + proc->owner = THIS_MODULE; + } + } +#endif + + printk("ip_tables: (C) 2000-2002 Netfilter core team\n"); return 0; } static void __exit fini(void) { nf_unregister_sockopt(&ipt_sockopts); - - xt_unregister_match(AF_INET, &icmp_matchstruct); - xt_unregister_target(AF_INET, &ipt_error_target); - xt_unregister_target(AF_INET, &ipt_standard_target); - - xt_proto_fini(AF_INET); +#ifdef CONFIG_PROC_FS + { + int i; + for (i = 0; ipt_proc_entry[i].name; i++) + proc_net_remove(ipt_proc_entry[i].name); + } +#endif } EXPORT_SYMBOL(ipt_register_table); EXPORT_SYMBOL(ipt_unregister_table); +EXPORT_SYMBOL(ipt_register_match); +EXPORT_SYMBOL(ipt_unregister_match); EXPORT_SYMBOL(ipt_do_table); +EXPORT_SYMBOL(ipt_register_target); +EXPORT_SYMBOL(ipt_unregister_target); +EXPORT_SYMBOL(ipt_find_target); + module_init(init); module_exit(fini); diff --git a/trunk/net/netfilter/xt_CLASSIFY.c b/trunk/net/ipv4/netfilter/ipt_CLASSIFY.c similarity index 66% rename from trunk/net/netfilter/xt_CLASSIFY.c rename to trunk/net/ipv4/netfilter/ipt_CLASSIFY.c index 78ee266a12ee..dab78d8bd494 100644 --- a/trunk/net/netfilter/xt_CLASSIFY.c +++ b/trunk/net/ipv4/netfilter/ipt_CLASSIFY.c @@ -15,13 +15,12 @@ #include #include -#include -#include +#include +#include MODULE_AUTHOR("Patrick McHardy "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("iptables qdisc classification target module"); -MODULE_ALIAS("ipt_CLASSIFY"); static unsigned int target(struct sk_buff **pskb, @@ -31,25 +30,25 @@ target(struct sk_buff **pskb, const void *targinfo, void *userinfo) { - const struct xt_classify_target_info *clinfo = targinfo; + const struct ipt_classify_target_info *clinfo = targinfo; - if ((*pskb)->priority != clinfo->priority) + if((*pskb)->priority != clinfo->priority) (*pskb)->priority = clinfo->priority; - return XT_CONTINUE; + return IPT_CONTINUE; } static int checkentry(const char *tablename, - const void *e, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { - if (targinfosize != XT_ALIGN(sizeof(struct xt_classify_target_info))){ + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_classify_target_info))){ printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n", targinfosize, - XT_ALIGN(sizeof(struct xt_classify_target_info))); + IPT_ALIGN(sizeof(struct ipt_classify_target_info))); return 0; } @@ -70,39 +69,21 @@ checkentry(const char *tablename, return 1; } -static struct xt_target classify_reg = { - .name = "CLASSIFY", - .target = target, - .checkentry = checkentry, - .me = THIS_MODULE, -}; -static struct xt_target classify6_reg = { +static struct ipt_target ipt_classify_reg = { .name = "CLASSIFY", .target = target, .checkentry = checkentry, .me = THIS_MODULE, }; - static int __init init(void) { - int ret; - - ret = xt_register_target(AF_INET, &classify_reg); - if (ret) - return ret; - - ret = xt_register_target(AF_INET6, &classify6_reg); - if (ret) - xt_unregister_target(AF_INET, &classify_reg); - - return ret; + return ipt_register_target(&ipt_classify_reg); } static void __exit fini(void) { - xt_unregister_target(AF_INET, &classify_reg); - xt_unregister_target(AF_INET6, &classify6_reg); + ipt_unregister_target(&ipt_classify_reg); } module_init(init); diff --git a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c index d9bc971f03af..45c52d8f4d99 100644 --- a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -379,13 +379,12 @@ target(struct sk_buff **pskb, static int checkentry(const char *tablename, - const void *e_void, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { struct ipt_clusterip_tgt_info *cipinfo = targinfo; - const struct ipt_entry *e = e_void; struct clusterip_config *config; diff --git a/trunk/net/netfilter/xt_CONNMARK.c b/trunk/net/ipv4/netfilter/ipt_CONNMARK.c similarity index 73% rename from trunk/net/netfilter/xt_CONNMARK.c rename to trunk/net/ipv4/netfilter/ipt_CONNMARK.c index 22506e376be5..8acac5a40a92 100644 --- a/trunk/net/netfilter/xt_CONNMARK.c +++ b/trunk/net/ipv4/netfilter/ipt_CONNMARK.c @@ -26,10 +26,9 @@ MODULE_AUTHOR("Henrik Nordstrom "); MODULE_DESCRIPTION("IP tables CONNMARK matching module"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ipt_CONNMARK"); -#include -#include +#include +#include #include static unsigned int @@ -40,7 +39,7 @@ target(struct sk_buff **pskb, const void *targinfo, void *userinfo) { - const struct xt_connmark_target_info *markinfo = targinfo; + const struct ipt_connmark_target_info *markinfo = targinfo; u_int32_t diff; u_int32_t nfmark; u_int32_t newmark; @@ -49,17 +48,17 @@ target(struct sk_buff **pskb, if (ctmark) { switch(markinfo->mode) { - case XT_CONNMARK_SET: + case IPT_CONNMARK_SET: newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; if (newmark != *ctmark) *ctmark = newmark; break; - case XT_CONNMARK_SAVE: + case IPT_CONNMARK_SAVE: newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); if (*ctmark != newmark) *ctmark = newmark; break; - case XT_CONNMARK_RESTORE: + case IPT_CONNMARK_RESTORE: nfmark = (*pskb)->nfmark; diff = (*ctmark ^ nfmark) & markinfo->mask; if (diff != 0) @@ -68,25 +67,25 @@ target(struct sk_buff **pskb, } } - return XT_CONTINUE; + return IPT_CONTINUE; } static int checkentry(const char *tablename, - const void *entry, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { - struct xt_connmark_target_info *matchinfo = targinfo; - if (targinfosize != XT_ALIGN(sizeof(struct xt_connmark_target_info))) { + struct ipt_connmark_target_info *matchinfo = targinfo; + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) { printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", targinfosize, - XT_ALIGN(sizeof(struct xt_connmark_target_info))); + IPT_ALIGN(sizeof(struct ipt_connmark_target_info))); return 0; } - if (matchinfo->mode == XT_CONNMARK_RESTORE) { + if (matchinfo->mode == IPT_CONNMARK_RESTORE) { if (strcmp(tablename, "mangle") != 0) { printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); return 0; @@ -101,13 +100,7 @@ checkentry(const char *tablename, return 1; } -static struct xt_target connmark_reg = { - .name = "CONNMARK", - .target = &target, - .checkentry = &checkentry, - .me = THIS_MODULE -}; -static struct xt_target connmark6_reg = { +static struct ipt_target ipt_connmark_reg = { .name = "CONNMARK", .target = &target, .checkentry = &checkentry, @@ -116,25 +109,13 @@ static struct xt_target connmark6_reg = { static int __init init(void) { - int ret; - - need_conntrack(); - - ret = xt_register_target(AF_INET, &connmark_reg); - if (ret) - return ret; - - ret = xt_register_target(AF_INET6, &connmark6_reg); - if (ret) - xt_unregister_target(AF_INET, &connmark_reg); - - return ret; + need_ip_conntrack(); + return ipt_register_target(&ipt_connmark_reg); } static void __exit fini(void) { - xt_unregister_target(AF_INET, &connmark_reg); - xt_unregister_target(AF_INET6, &connmark6_reg); + ipt_unregister_target(&ipt_connmark_reg); } module_init(init); diff --git a/trunk/net/ipv4/netfilter/ipt_DSCP.c b/trunk/net/ipv4/netfilter/ipt_DSCP.c index 898cdf79ce18..6e319570a28c 100644 --- a/trunk/net/ipv4/netfilter/ipt_DSCP.c +++ b/trunk/net/ipv4/netfilter/ipt_DSCP.c @@ -57,7 +57,7 @@ target(struct sk_buff **pskb, static int checkentry(const char *tablename, - const void *e_void, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_ECN.c b/trunk/net/ipv4/netfilter/ipt_ECN.c index 706445426a6d..a1319693f648 100644 --- a/trunk/net/ipv4/netfilter/ipt_ECN.c +++ b/trunk/net/ipv4/netfilter/ipt_ECN.c @@ -113,13 +113,12 @@ target(struct sk_buff **pskb, static int checkentry(const char *tablename, - const void *e_void, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo; - const struct ipt_entry *e = e_void; if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ECN_info))) { printk(KERN_WARNING "ECN: targinfosize %u != %Zu\n", diff --git a/trunk/net/ipv4/netfilter/ipt_LOG.c b/trunk/net/ipv4/netfilter/ipt_LOG.c index 6606ddb66a29..30be0f1dae37 100644 --- a/trunk/net/ipv4/netfilter/ipt_LOG.c +++ b/trunk/net/ipv4/netfilter/ipt_LOG.c @@ -431,7 +431,7 @@ ipt_log_target(struct sk_buff **pskb, } static int ipt_log_checkentry(const char *tablename, - const void *e, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/netfilter/xt_MARK.c b/trunk/net/ipv4/netfilter/ipt_MARK.c similarity index 61% rename from trunk/net/netfilter/xt_MARK.c rename to trunk/net/ipv4/netfilter/ipt_MARK.c index 0c11ee9550f3..52b4f2c296bf 100644 --- a/trunk/net/netfilter/xt_MARK.c +++ b/trunk/net/ipv4/netfilter/ipt_MARK.c @@ -12,14 +12,12 @@ #include #include -#include -#include +#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marc Boucher "); -MODULE_DESCRIPTION("ip[6]tables MARK modification module"); -MODULE_ALIAS("ipt_MARK"); -MODULE_ALIAS("ip6t_MARK"); +MODULE_DESCRIPTION("iptables MARK modification module"); static unsigned int target_v0(struct sk_buff **pskb, @@ -29,12 +27,12 @@ target_v0(struct sk_buff **pskb, const void *targinfo, void *userinfo) { - const struct xt_mark_target_info *markinfo = targinfo; + const struct ipt_mark_target_info *markinfo = targinfo; if((*pskb)->nfmark != markinfo->mark) (*pskb)->nfmark = markinfo->mark; - return XT_CONTINUE; + return IPT_CONTINUE; } static unsigned int @@ -45,19 +43,19 @@ target_v1(struct sk_buff **pskb, const void *targinfo, void *userinfo) { - const struct xt_mark_target_info_v1 *markinfo = targinfo; + const struct ipt_mark_target_info_v1 *markinfo = targinfo; int mark = 0; switch (markinfo->mode) { - case XT_MARK_SET: + case IPT_MARK_SET: mark = markinfo->mark; break; - case XT_MARK_AND: + case IPT_MARK_AND: mark = (*pskb)->nfmark & markinfo->mark; break; - case XT_MARK_OR: + case IPT_MARK_OR: mark = (*pskb)->nfmark | markinfo->mark; break; } @@ -65,23 +63,23 @@ target_v1(struct sk_buff **pskb, if((*pskb)->nfmark != mark) (*pskb)->nfmark = mark; - return XT_CONTINUE; + return IPT_CONTINUE; } static int checkentry_v0(const char *tablename, - const void *entry, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { - struct xt_mark_target_info *markinfo = targinfo; + struct ipt_mark_target_info *markinfo = targinfo; - if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info))) { + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) { printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", targinfosize, - XT_ALIGN(sizeof(struct xt_mark_target_info))); + IPT_ALIGN(sizeof(struct ipt_mark_target_info))); return 0; } @@ -100,17 +98,17 @@ checkentry_v0(const char *tablename, static int checkentry_v1(const char *tablename, - const void *entry, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { - struct xt_mark_target_info_v1 *markinfo = targinfo; + struct ipt_mark_target_info_v1 *markinfo = targinfo; - if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info_v1))){ + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))){ printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", targinfosize, - XT_ALIGN(sizeof(struct xt_mark_target_info_v1))); + IPT_ALIGN(sizeof(struct ipt_mark_target_info_v1))); return 0; } @@ -119,9 +117,9 @@ checkentry_v1(const char *tablename, return 0; } - if (markinfo->mode != XT_MARK_SET - && markinfo->mode != XT_MARK_AND - && markinfo->mode != XT_MARK_OR) { + if (markinfo->mode != IPT_MARK_SET + && markinfo->mode != IPT_MARK_AND + && markinfo->mode != IPT_MARK_OR) { printk(KERN_WARNING "MARK: unknown mode %u\n", markinfo->mode); return 0; @@ -135,7 +133,7 @@ checkentry_v1(const char *tablename, return 1; } -static struct xt_target ipt_mark_reg_v0 = { +static struct ipt_target ipt_mark_reg_v0 = { .name = "MARK", .target = target_v0, .checkentry = checkentry_v0, @@ -143,7 +141,7 @@ static struct xt_target ipt_mark_reg_v0 = { .revision = 0, }; -static struct xt_target ipt_mark_reg_v1 = { +static struct ipt_target ipt_mark_reg_v1 = { .name = "MARK", .target = target_v1, .checkentry = checkentry_v1, @@ -151,40 +149,23 @@ static struct xt_target ipt_mark_reg_v1 = { .revision = 1, }; -static struct xt_target ip6t_mark_reg_v0 = { - .name = "MARK", - .target = target_v0, - .checkentry = checkentry_v0, - .me = THIS_MODULE, - .revision = 0, -}; - static int __init init(void) { int err; - err = xt_register_target(AF_INET, &ipt_mark_reg_v0); - if (err) - return err; - - err = xt_register_target(AF_INET, &ipt_mark_reg_v1); - if (err) - xt_unregister_target(AF_INET, &ipt_mark_reg_v0); - - err = xt_register_target(AF_INET6, &ip6t_mark_reg_v0); - if (err) { - xt_unregister_target(AF_INET, &ipt_mark_reg_v0); - xt_unregister_target(AF_INET, &ipt_mark_reg_v1); + err = ipt_register_target(&ipt_mark_reg_v0); + if (!err) { + err = ipt_register_target(&ipt_mark_reg_v1); + if (err) + ipt_unregister_target(&ipt_mark_reg_v0); } - return err; } static void __exit fini(void) { - xt_unregister_target(AF_INET, &ipt_mark_reg_v0); - xt_unregister_target(AF_INET, &ipt_mark_reg_v1); - xt_unregister_target(AF_INET6, &ip6t_mark_reg_v0); + ipt_unregister_target(&ipt_mark_reg_v0); + ipt_unregister_target(&ipt_mark_reg_v1); } module_init(init); diff --git a/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c b/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c index 12c56d3343ca..27860510ca6d 100644 --- a/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/trunk/net/ipv4/netfilter/ipt_MASQUERADE.c @@ -40,7 +40,7 @@ static DEFINE_RWLOCK(masq_lock); /* FIXME: Multiple targets. --RR */ static int masquerade_check(const char *tablename, - const void *e, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_NETMAP.c b/trunk/net/ipv4/netfilter/ipt_NETMAP.c index b074467fe67b..e6e7b6095363 100644 --- a/trunk/net/ipv4/netfilter/ipt_NETMAP.c +++ b/trunk/net/ipv4/netfilter/ipt_NETMAP.c @@ -31,7 +31,7 @@ MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target"); static int check(const char *tablename, - const void *e, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_NFQUEUE.c b/trunk/net/ipv4/netfilter/ipt_NFQUEUE.c new file mode 100644 index 000000000000..3cedc9be8807 --- /dev/null +++ b/trunk/net/ipv4/netfilter/ipt_NFQUEUE.c @@ -0,0 +1,70 @@ +/* iptables module for using new netfilter netlink queue + * + * (C) 2005 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("iptables NFQUEUE target"); +MODULE_LICENSE("GPL"); + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + const struct ipt_NFQ_info *tinfo = targinfo; + + return NF_QUEUE_NR(tinfo->queuenum); +} + +static int +checkentry(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_NFQ_info))) { + printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", + targinfosize, + IPT_ALIGN(sizeof(struct ipt_NFQ_info))); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_NFQ_reg = { + .name = "NFQUEUE", + .target = target, + .checkentry = checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_target(&ipt_NFQ_reg); +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_NFQ_reg); +} + +module_init(init); +module_exit(fini); diff --git a/trunk/net/netfilter/xt_NOTRACK.c b/trunk/net/ipv4/netfilter/ipt_NOTRACK.c similarity index 69% rename from trunk/net/netfilter/xt_NOTRACK.c rename to trunk/net/ipv4/netfilter/ipt_NOTRACK.c index 24d477afa939..e3c69d072c6e 100644 --- a/trunk/net/netfilter/xt_NOTRACK.c +++ b/trunk/net/ipv4/netfilter/ipt_NOTRACK.c @@ -4,12 +4,9 @@ #include #include -#include +#include #include -MODULE_LICENSE("GPL"); -MODULE_ALIAS("ipt_NOTRACK"); - static unsigned int target(struct sk_buff **pskb, const struct net_device *in, @@ -20,7 +17,7 @@ target(struct sk_buff **pskb, { /* Previously seen (loopback)? Ignore. */ if ((*pskb)->nfct != NULL) - return XT_CONTINUE; + return IPT_CONTINUE; /* Attach fake conntrack entry. If there is a real ct entry correspondig to this packet, @@ -30,12 +27,12 @@ target(struct sk_buff **pskb, (*pskb)->nfctinfo = IP_CT_NEW; nf_conntrack_get((*pskb)->nfct); - return XT_CONTINUE; + return IPT_CONTINUE; } static int checkentry(const char *tablename, - const void *entry, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) @@ -54,39 +51,26 @@ checkentry(const char *tablename, return 1; } -static struct xt_target notrack_reg = { +static struct ipt_target ipt_notrack_reg = { .name = "NOTRACK", .target = target, .checkentry = checkentry, - .me = THIS_MODULE, -}; -static struct xt_target notrack6_reg = { - .name = "NOTRACK", - .target = target, - .checkentry = checkentry, - .me = THIS_MODULE, + .me = THIS_MODULE }; static int __init init(void) { - int ret; - - ret = xt_register_target(AF_INET, ¬rack_reg); - if (ret) - return ret; + if (ipt_register_target(&ipt_notrack_reg)) + return -EINVAL; - ret = xt_register_target(AF_INET6, ¬rack6_reg); - if (ret) - xt_unregister_target(AF_INET, ¬rack_reg); - - return ret; + return 0; } static void __exit fini(void) { - xt_unregister_target(AF_INET6, ¬rack6_reg); - xt_unregister_target(AF_INET, ¬rack_reg); + ipt_unregister_target(&ipt_notrack_reg); } module_init(init); module_exit(fini); +MODULE_LICENSE("GPL"); diff --git a/trunk/net/ipv4/netfilter/ipt_REDIRECT.c b/trunk/net/ipv4/netfilter/ipt_REDIRECT.c index 140be51f2f01..5245bfd33d52 100644 --- a/trunk/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/trunk/net/ipv4/netfilter/ipt_REDIRECT.c @@ -33,7 +33,7 @@ MODULE_DESCRIPTION("iptables REDIRECT target module"); /* FIXME: Take multiple ranges --RR */ static int redirect_check(const char *tablename, - const void *e, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_REJECT.c b/trunk/net/ipv4/netfilter/ipt_REJECT.c index 3eb47aae78c5..6693526ae128 100644 --- a/trunk/net/ipv4/netfilter/ipt_REJECT.c +++ b/trunk/net/ipv4/netfilter/ipt_REJECT.c @@ -282,13 +282,12 @@ static unsigned int reject(struct sk_buff **pskb, } static int check(const char *tablename, - const void *e_void, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { const struct ipt_reject_info *rejinfo = targinfo; - const struct ipt_entry *e = e_void; if (targinfosize != IPT_ALIGN(sizeof(struct ipt_reject_info))) { DEBUGP("REJECT: targinfosize %u != 0\n", targinfosize); diff --git a/trunk/net/ipv4/netfilter/ipt_SAME.c b/trunk/net/ipv4/netfilter/ipt_SAME.c index a22de59bba0e..7a0536d864ac 100644 --- a/trunk/net/ipv4/netfilter/ipt_SAME.c +++ b/trunk/net/ipv4/netfilter/ipt_SAME.c @@ -49,7 +49,7 @@ MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip"); static int same_check(const char *tablename, - const void *e, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_TCPMSS.c b/trunk/net/ipv4/netfilter/ipt_TCPMSS.c index c122841e182c..8db70d6908c3 100644 --- a/trunk/net/ipv4/netfilter/ipt_TCPMSS.c +++ b/trunk/net/ipv4/netfilter/ipt_TCPMSS.c @@ -210,13 +210,12 @@ static inline int find_syn_match(const struct ipt_entry_match *m) /* Must specify -p tcp --syn/--tcp-flags SYN */ static int ipt_tcpmss_checkentry(const char *tablename, - const void *e_void, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { const struct ipt_tcpmss_info *tcpmssinfo = targinfo; - const struct ipt_entry *e = e_void; if (targinfosize != IPT_ALIGN(sizeof(struct ipt_tcpmss_info))) { DEBUGP("ipt_tcpmss_checkentry: targinfosize %u != %u\n", diff --git a/trunk/net/ipv4/netfilter/ipt_TOS.c b/trunk/net/ipv4/netfilter/ipt_TOS.c index 3a44a56db239..deadb36d4428 100644 --- a/trunk/net/ipv4/netfilter/ipt_TOS.c +++ b/trunk/net/ipv4/netfilter/ipt_TOS.c @@ -52,7 +52,7 @@ target(struct sk_buff **pskb, static int checkentry(const char *tablename, - const void *e_void, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_TTL.c b/trunk/net/ipv4/netfilter/ipt_TTL.c index b769eb231970..b9ae6a9382f3 100644 --- a/trunk/net/ipv4/netfilter/ipt_TTL.c +++ b/trunk/net/ipv4/netfilter/ipt_TTL.c @@ -66,7 +66,7 @@ ipt_ttl_target(struct sk_buff **pskb, const struct net_device *in, } static int ipt_ttl_checkentry(const char *tablename, - const void *e, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_ULOG.c b/trunk/net/ipv4/netfilter/ipt_ULOG.c index 641dbc477650..38641cd06123 100644 --- a/trunk/net/ipv4/netfilter/ipt_ULOG.c +++ b/trunk/net/ipv4/netfilter/ipt_ULOG.c @@ -330,7 +330,7 @@ static void ipt_logfn(unsigned int pf, } static int ipt_ulog_checkentry(const char *tablename, - const void *e, + const struct ipt_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hookmask) diff --git a/trunk/net/ipv4/netfilter/ipt_addrtype.c b/trunk/net/ipv4/netfilter/ipt_addrtype.c index d6b83a976518..e19c2a52d00c 100644 --- a/trunk/net/ipv4/netfilter/ipt_addrtype.c +++ b/trunk/net/ipv4/netfilter/ipt_addrtype.c @@ -29,7 +29,7 @@ static inline int match_type(u_int32_t addr, u_int16_t mask) static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, - int offset, unsigned int protoff, int *hotdrop) + int offset, int *hotdrop) { const struct ipt_addrtype_info *info = matchinfo; const struct iphdr *iph = skb->nh.iph; @@ -43,7 +43,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, return ret; } -static int checkentry(const char *tablename, const void *ip, +static int checkentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { diff --git a/trunk/net/ipv4/netfilter/ipt_ah.c b/trunk/net/ipv4/netfilter/ipt_ah.c index 144adfec13cc..a0fea847cb72 100644 --- a/trunk/net/ipv4/netfilter/ipt_ah.c +++ b/trunk/net/ipv4/netfilter/ipt_ah.c @@ -41,7 +41,6 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { struct ip_auth_hdr _ahdr, *ah; @@ -51,7 +50,7 @@ match(const struct sk_buff *skb, if (offset) return 0; - ah = skb_header_pointer(skb, protoff, + ah = skb_header_pointer(skb, skb->nh.iph->ihl * 4, sizeof(_ahdr), &_ahdr); if (ah == NULL) { /* We've been asked to examine this packet, and we @@ -70,13 +69,12 @@ match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *ip_void, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchinfosize, unsigned int hook_mask) { const struct ipt_ah *ahinfo = matchinfo; - const struct ipt_ip *ip = ip_void; /* Must specify proto == AH, and no unknown invflags */ if (ip->proto != IPPROTO_AH || (ip->invflags & IPT_INV_PROTO)) { diff --git a/trunk/net/netfilter/xt_comment.c b/trunk/net/ipv4/netfilter/ipt_comment.c similarity index 55% rename from trunk/net/netfilter/xt_comment.c rename to trunk/net/ipv4/netfilter/ipt_comment.c index 4ba6fd65c6e9..6b76a1ea5245 100644 --- a/trunk/net/netfilter/xt_comment.c +++ b/trunk/net/ipv4/netfilter/ipt_comment.c @@ -6,14 +6,12 @@ #include #include -#include -#include +#include +#include MODULE_AUTHOR("Brad Fisher "); MODULE_DESCRIPTION("iptables comment match module"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ipt_comment"); -MODULE_ALIAS("ip6t_comment"); static int match(const struct sk_buff *skb, @@ -21,7 +19,6 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protooff, int *hotdrop) { /* We always match */ @@ -30,25 +27,18 @@ match(const struct sk_buff *skb, static int checkentry(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { /* Check the size */ - if (matchsize != XT_ALIGN(sizeof(struct xt_comment_info))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_comment_info))) return 0; return 1; } -static struct xt_match comment_match = { - .name = "comment", - .match = match, - .checkentry = checkentry, - .me = THIS_MODULE -}; - -static struct xt_match comment6_match = { +static struct ipt_match comment_match = { .name = "comment", .match = match, .checkentry = checkentry, @@ -57,23 +47,12 @@ static struct xt_match comment6_match = { static int __init init(void) { - int ret; - - ret = xt_register_match(AF_INET, &comment_match); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &comment6_match); - if (ret) - xt_unregister_match(AF_INET, &comment_match); - - return ret; + return ipt_register_match(&comment_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &comment_match); - xt_unregister_match(AF_INET6, &comment6_match); + ipt_unregister_match(&comment_match); } module_init(init); diff --git a/trunk/net/netfilter/xt_connbytes.c b/trunk/net/ipv4/netfilter/ipt_connbytes.c similarity index 66% rename from trunk/net/netfilter/xt_connbytes.c rename to trunk/net/ipv4/netfilter/ipt_connbytes.c index 150d2a4b0f71..d68a048b7176 100644 --- a/trunk/net/netfilter/xt_connbytes.c +++ b/trunk/net/ipv4/netfilter/ipt_connbytes.c @@ -6,15 +6,13 @@ * - add functionality to match number of packets * - add functionality to match average packet size * - add support to match directions seperately - * 2005-10-16 Harald Welte - * - Port to x_tables * */ #include #include #include -#include -#include +#include +#include #include #include @@ -22,7 +20,6 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte "); MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection"); -MODULE_ALIAS("ipt_connbytes"); /* 64bit divisor, dividend and result. dynamic precision */ static u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor) @@ -46,10 +43,9 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_connbytes_info *sinfo = matchinfo; + const struct ipt_connbytes_info *sinfo = matchinfo; u_int64_t what = 0; /* initialize to make gcc happy */ const struct ip_conntrack_counter *counters; @@ -57,45 +53,45 @@ match(const struct sk_buff *skb, return 0; /* no match */ switch (sinfo->what) { - case XT_CONNBYTES_PKTS: + case IPT_CONNBYTES_PKTS: switch (sinfo->direction) { - case XT_CONNBYTES_DIR_ORIGINAL: + case IPT_CONNBYTES_DIR_ORIGINAL: what = counters[IP_CT_DIR_ORIGINAL].packets; break; - case XT_CONNBYTES_DIR_REPLY: + case IPT_CONNBYTES_DIR_REPLY: what = counters[IP_CT_DIR_REPLY].packets; break; - case XT_CONNBYTES_DIR_BOTH: + case IPT_CONNBYTES_DIR_BOTH: what = counters[IP_CT_DIR_ORIGINAL].packets; what += counters[IP_CT_DIR_REPLY].packets; break; } break; - case XT_CONNBYTES_BYTES: + case IPT_CONNBYTES_BYTES: switch (sinfo->direction) { - case XT_CONNBYTES_DIR_ORIGINAL: + case IPT_CONNBYTES_DIR_ORIGINAL: what = counters[IP_CT_DIR_ORIGINAL].bytes; break; - case XT_CONNBYTES_DIR_REPLY: + case IPT_CONNBYTES_DIR_REPLY: what = counters[IP_CT_DIR_REPLY].bytes; break; - case XT_CONNBYTES_DIR_BOTH: + case IPT_CONNBYTES_DIR_BOTH: what = counters[IP_CT_DIR_ORIGINAL].bytes; what += counters[IP_CT_DIR_REPLY].bytes; break; } break; - case XT_CONNBYTES_AVGPKT: + case IPT_CONNBYTES_AVGPKT: switch (sinfo->direction) { - case XT_CONNBYTES_DIR_ORIGINAL: + case IPT_CONNBYTES_DIR_ORIGINAL: what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes, counters[IP_CT_DIR_ORIGINAL].packets); break; - case XT_CONNBYTES_DIR_REPLY: + case IPT_CONNBYTES_DIR_REPLY: what = div64_64(counters[IP_CT_DIR_REPLY].bytes, counters[IP_CT_DIR_REPLY].packets); break; - case XT_CONNBYTES_DIR_BOTH: + case IPT_CONNBYTES_DIR_BOTH: { u_int64_t bytes; u_int64_t pkts; @@ -121,36 +117,30 @@ match(const struct sk_buff *skb, } static int check(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - const struct xt_connbytes_info *sinfo = matchinfo; + const struct ipt_connbytes_info *sinfo = matchinfo; - if (matchsize != XT_ALIGN(sizeof(struct xt_connbytes_info))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info))) return 0; - if (sinfo->what != XT_CONNBYTES_PKTS && - sinfo->what != XT_CONNBYTES_BYTES && - sinfo->what != XT_CONNBYTES_AVGPKT) + if (sinfo->what != IPT_CONNBYTES_PKTS && + sinfo->what != IPT_CONNBYTES_BYTES && + sinfo->what != IPT_CONNBYTES_AVGPKT) return 0; - if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL && - sinfo->direction != XT_CONNBYTES_DIR_REPLY && - sinfo->direction != XT_CONNBYTES_DIR_BOTH) + if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL && + sinfo->direction != IPT_CONNBYTES_DIR_REPLY && + sinfo->direction != IPT_CONNBYTES_DIR_BOTH) return 0; return 1; } -static struct xt_match connbytes_match = { - .name = "connbytes", - .match = &match, - .checkentry = &check, - .me = THIS_MODULE -}; -static struct xt_match connbytes6_match = { +static struct ipt_match state_match = { .name = "connbytes", .match = &match, .checkentry = &check, @@ -159,21 +149,12 @@ static struct xt_match connbytes6_match = { static int __init init(void) { - int ret; - ret = xt_register_match(AF_INET, &connbytes_match); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &connbytes6_match); - if (ret) - xt_unregister_match(AF_INET, &connbytes_match); - return ret; + return ipt_register_match(&state_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &connbytes_match); - xt_unregister_match(AF_INET6, &connbytes6_match); + ipt_unregister_match(&state_match); } module_init(init); diff --git a/trunk/net/netfilter/xt_connmark.c b/trunk/net/ipv4/netfilter/ipt_connmark.c similarity index 70% rename from trunk/net/netfilter/xt_connmark.c rename to trunk/net/ipv4/netfilter/ipt_connmark.c index d06e925032da..5306ef293b92 100644 --- a/trunk/net/netfilter/xt_connmark.c +++ b/trunk/net/ipv4/netfilter/ipt_connmark.c @@ -25,10 +25,9 @@ MODULE_AUTHOR("Henrik Nordstrom "); MODULE_DESCRIPTION("IP tables connmark match module"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ipt_connmark"); -#include -#include +#include +#include #include static int @@ -37,10 +36,9 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_connmark_info *info = matchinfo; + const struct ipt_connmark_info *info = matchinfo; u_int32_t ctinfo; const u_int32_t *ctmark = nf_ct_get_mark(skb, &ctinfo); if (!ctmark) @@ -51,14 +49,14 @@ match(const struct sk_buff *skb, static int checkentry(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - struct xt_connmark_info *cm = - (struct xt_connmark_info *)matchinfo; - if (matchsize != XT_ALIGN(sizeof(struct xt_connmark_info))) + struct ipt_connmark_info *cm = + (struct ipt_connmark_info *)matchinfo; + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info))) return 0; if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { @@ -69,40 +67,21 @@ checkentry(const char *tablename, return 1; } -static struct xt_match connmark_match = { - .name = "connmark", - .match = &match, - .checkentry = &checkentry, - .me = THIS_MODULE -}; -static struct xt_match connmark6_match = { +static struct ipt_match connmark_match = { .name = "connmark", .match = &match, .checkentry = &checkentry, .me = THIS_MODULE }; - static int __init init(void) { - int ret; - - need_conntrack(); - - ret = xt_register_match(AF_INET, &connmark_match); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &connmark6_match); - if (ret) - xt_unregister_match(AF_INET, &connmark_match); - return ret; + return ipt_register_match(&connmark_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET6, &connmark6_match); - xt_unregister_match(AF_INET, &connmark_match); + ipt_unregister_match(&connmark_match); } module_init(init); diff --git a/trunk/net/netfilter/xt_conntrack.c b/trunk/net/ipv4/netfilter/ipt_conntrack.c similarity index 63% rename from trunk/net/netfilter/xt_conntrack.c rename to trunk/net/ipv4/netfilter/ipt_conntrack.c index ffdebc95eb95..c8d18705469b 100644 --- a/trunk/net/netfilter/xt_conntrack.c +++ b/trunk/net/ipv4/netfilter/ipt_conntrack.c @@ -18,13 +18,12 @@ #include #endif -#include -#include +#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marc Boucher "); MODULE_DESCRIPTION("iptables connection tracking match module"); -MODULE_ALIAS("ipt_conntrack"); #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) @@ -34,10 +33,9 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_conntrack_info *sinfo = matchinfo; + const struct ipt_conntrack_info *sinfo = matchinfo; struct ip_conntrack *ct; enum ip_conntrack_info ctinfo; unsigned int statebit; @@ -47,58 +45,58 @@ match(const struct sk_buff *skb, #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) if (ct == &ip_conntrack_untracked) - statebit = XT_CONNTRACK_STATE_UNTRACKED; + statebit = IPT_CONNTRACK_STATE_UNTRACKED; else if (ct) - statebit = XT_CONNTRACK_STATE_BIT(ctinfo); + statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); else - statebit = XT_CONNTRACK_STATE_INVALID; + statebit = IPT_CONNTRACK_STATE_INVALID; - if(sinfo->flags & XT_CONNTRACK_STATE) { + if(sinfo->flags & IPT_CONNTRACK_STATE) { if (ct) { if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip != ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip) - statebit |= XT_CONNTRACK_STATE_SNAT; + statebit |= IPT_CONNTRACK_STATE_SNAT; if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip != ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip) - statebit |= XT_CONNTRACK_STATE_DNAT; + statebit |= IPT_CONNTRACK_STATE_DNAT; } - if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE)) + if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) return 0; } - if(sinfo->flags & XT_CONNTRACK_PROTO) { - if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO)) + if(sinfo->flags & IPT_CONNTRACK_PROTO) { + if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO)) return 0; } - if(sinfo->flags & XT_CONNTRACK_ORIGSRC) { - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, XT_CONNTRACK_ORIGSRC)) + if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC)) return 0; } - if(sinfo->flags & XT_CONNTRACK_ORIGDST) { - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, XT_CONNTRACK_ORIGDST)) + if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST)) return 0; } - if(sinfo->flags & XT_CONNTRACK_REPLSRC) { - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, XT_CONNTRACK_REPLSRC)) + if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC)) return 0; } - if(sinfo->flags & XT_CONNTRACK_REPLDST) { - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, XT_CONNTRACK_REPLDST)) + if(sinfo->flags & IPT_CONNTRACK_REPLDST) { + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST)) return 0; } - if(sinfo->flags & XT_CONNTRACK_STATUS) { - if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS)) + if(sinfo->flags & IPT_CONNTRACK_STATUS) { + if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) return 0; } - if(sinfo->flags & XT_CONNTRACK_EXPIRES) { + if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { unsigned long expires; if(!ct) @@ -106,7 +104,7 @@ match(const struct sk_buff *skb, expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; - if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES)) + if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) return 0; } @@ -120,10 +118,9 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_conntrack_info *sinfo = matchinfo; + const struct ipt_conntrack_info *sinfo = matchinfo; struct nf_conn *ct; enum ip_conntrack_info ctinfo; unsigned int statebit; @@ -133,58 +130,58 @@ match(const struct sk_buff *skb, #define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg)) if (ct == &nf_conntrack_untracked) - statebit = XT_CONNTRACK_STATE_UNTRACKED; + statebit = IPT_CONNTRACK_STATE_UNTRACKED; else if (ct) - statebit = XT_CONNTRACK_STATE_BIT(ctinfo); + statebit = IPT_CONNTRACK_STATE_BIT(ctinfo); else - statebit = XT_CONNTRACK_STATE_INVALID; + statebit = IPT_CONNTRACK_STATE_INVALID; - if(sinfo->flags & XT_CONNTRACK_STATE) { + if(sinfo->flags & IPT_CONNTRACK_STATE) { if (ct) { if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip != ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip) - statebit |= XT_CONNTRACK_STATE_SNAT; + statebit |= IPT_CONNTRACK_STATE_SNAT; if(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip != ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip) - statebit |= XT_CONNTRACK_STATE_DNAT; + statebit |= IPT_CONNTRACK_STATE_DNAT; } - if (FWINV((statebit & sinfo->statemask) == 0, XT_CONNTRACK_STATE)) + if (FWINV((statebit & sinfo->statemask) == 0, IPT_CONNTRACK_STATE)) return 0; } - if(sinfo->flags & XT_CONNTRACK_PROTO) { - if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, XT_CONNTRACK_PROTO)) + if(sinfo->flags & IPT_CONNTRACK_PROTO) { + if (!ct || FWINV(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum, IPT_CONNTRACK_PROTO)) return 0; } - if(sinfo->flags & XT_CONNTRACK_ORIGSRC) { - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, XT_CONNTRACK_ORIGSRC)) + if(sinfo->flags & IPT_CONNTRACK_ORIGSRC) { + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip, IPT_CONNTRACK_ORIGSRC)) return 0; } - if(sinfo->flags & XT_CONNTRACK_ORIGDST) { - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, XT_CONNTRACK_ORIGDST)) + if(sinfo->flags & IPT_CONNTRACK_ORIGDST) { + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) != sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip, IPT_CONNTRACK_ORIGDST)) return 0; } - if(sinfo->flags & XT_CONNTRACK_REPLSRC) { - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, XT_CONNTRACK_REPLSRC)) + if(sinfo->flags & IPT_CONNTRACK_REPLSRC) { + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip&sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].src.ip, IPT_CONNTRACK_REPLSRC)) return 0; } - if(sinfo->flags & XT_CONNTRACK_REPLDST) { - if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, XT_CONNTRACK_REPLDST)) + if(sinfo->flags & IPT_CONNTRACK_REPLDST) { + if (!ct || FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip&sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) != sinfo->tuple[IP_CT_DIR_REPLY].dst.ip, IPT_CONNTRACK_REPLDST)) return 0; } - if(sinfo->flags & XT_CONNTRACK_STATUS) { - if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, XT_CONNTRACK_STATUS)) + if(sinfo->flags & IPT_CONNTRACK_STATUS) { + if (!ct || FWINV((ct->status & sinfo->statusmask) == 0, IPT_CONNTRACK_STATUS)) return 0; } - if(sinfo->flags & XT_CONNTRACK_EXPIRES) { + if(sinfo->flags & IPT_CONNTRACK_EXPIRES) { unsigned long expires; if(!ct) @@ -192,7 +189,7 @@ match(const struct sk_buff *skb, expires = timer_pending(&ct->timeout) ? (ct->timeout.expires - jiffies)/HZ : 0; - if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), XT_CONNTRACK_EXPIRES)) + if (FWINV(!(expires >= sinfo->expires_min && expires <= sinfo->expires_max), IPT_CONNTRACK_EXPIRES)) return 0; } @@ -202,18 +199,18 @@ match(const struct sk_buff *skb, #endif /* CONFIG_NF_IP_CONNTRACK */ static int check(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - if (matchsize != XT_ALIGN(sizeof(struct xt_conntrack_info))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_conntrack_info))) return 0; return 1; } -static struct xt_match conntrack_match = { +static struct ipt_match conntrack_match = { .name = "conntrack", .match = &match, .checkentry = &check, @@ -222,16 +219,13 @@ static struct xt_match conntrack_match = { static int __init init(void) { - int ret; - need_conntrack(); - ret = xt_register_match(AF_INET, &conntrack_match); - - return ret; + need_ip_conntrack(); + return ipt_register_match(&conntrack_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &conntrack_match); + ipt_unregister_match(&conntrack_match); } module_init(init); diff --git a/trunk/net/netfilter/xt_dccp.c b/trunk/net/ipv4/netfilter/ipt_dccp.c similarity index 58% rename from trunk/net/netfilter/xt_dccp.c rename to trunk/net/ipv4/netfilter/ipt_dccp.c index 779f42fc9524..ad3278bba6c1 100644 --- a/trunk/net/netfilter/xt_dccp.c +++ b/trunk/net/ipv4/netfilter/ipt_dccp.c @@ -14,16 +14,8 @@ #include #include -#include -#include - #include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("Match for DCCP protocol packets"); -MODULE_ALIAS("ipt_dccp"); +#include #define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \ || (!!((invflag) & (option)) ^ (cond))) @@ -34,7 +26,6 @@ static DEFINE_SPINLOCK(dccp_buflock); static inline int dccp_find_option(u_int8_t option, const struct sk_buff *skb, - unsigned int protoff, const struct dccp_hdr *dh, int *hotdrop) { @@ -53,7 +44,9 @@ dccp_find_option(u_int8_t option, return 0; spin_lock_bh(&dccp_buflock); - op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf); + op = skb_header_pointer(skb, + skb->nh.iph->ihl*4 + optoff, + optlen, dccp_optbuf); if (op == NULL) { /* If we don't have the whole header, drop packet. */ spin_unlock_bh(&dccp_buflock); @@ -85,10 +78,10 @@ match_types(const struct dccp_hdr *dh, u_int16_t typemask) } static inline int -match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff, +match_option(u_int8_t option, const struct sk_buff *skb, const struct dccp_hdr *dh, int *hotdrop) { - return dccp_find_option(option, skb, protoff, dh, hotdrop); + return dccp_find_option(option, skb, dh, hotdrop); } static int @@ -97,17 +90,16 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_dccp_info *info = - (const struct xt_dccp_info *)matchinfo; + const struct ipt_dccp_info *info = + (const struct ipt_dccp_info *)matchinfo; struct dccp_hdr _dh, *dh; if (offset) return 0; - dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh); + dh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_dh), &_dh); if (dh == NULL) { *hotdrop = 1; return 0; @@ -115,73 +107,42 @@ match(const struct sk_buff *skb, return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0]) && (ntohs(dh->dccph_sport) <= info->spts[1])), - XT_DCCP_SRC_PORTS, info->flags, info->invflags) + IPT_DCCP_SRC_PORTS, info->flags, info->invflags) && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0]) && (ntohs(dh->dccph_dport) <= info->dpts[1])), - XT_DCCP_DEST_PORTS, info->flags, info->invflags) + IPT_DCCP_DEST_PORTS, info->flags, info->invflags) && DCCHECK(match_types(dh, info->typemask), - XT_DCCP_TYPE, info->flags, info->invflags) - && DCCHECK(match_option(info->option, skb, protoff, dh, - hotdrop), - XT_DCCP_OPTION, info->flags, info->invflags); + IPT_DCCP_TYPE, info->flags, info->invflags) + && DCCHECK(match_option(info->option, skb, dh, hotdrop), + IPT_DCCP_OPTION, info->flags, info->invflags); } static int checkentry(const char *tablename, - const void *inf, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - const struct ipt_ip *ip = inf; - const struct xt_dccp_info *info; + const struct ipt_dccp_info *info; - info = (const struct xt_dccp_info *)matchinfo; + info = (const struct ipt_dccp_info *)matchinfo; return ip->proto == IPPROTO_DCCP - && !(ip->invflags & XT_INV_PROTO) - && matchsize == XT_ALIGN(sizeof(struct xt_dccp_info)) - && !(info->flags & ~XT_DCCP_VALID_FLAGS) - && !(info->invflags & ~XT_DCCP_VALID_FLAGS) + && !(ip->invflags & IPT_INV_PROTO) + && matchsize == IPT_ALIGN(sizeof(struct ipt_dccp_info)) + && !(info->flags & ~IPT_DCCP_VALID_FLAGS) + && !(info->invflags & ~IPT_DCCP_VALID_FLAGS) && !(info->invflags & ~info->flags); } -static int -checkentry6(const char *tablename, - const void *inf, - void *matchinfo, - unsigned int matchsize, - unsigned int hook_mask) -{ - const struct ip6t_ip6 *ip = inf; - const struct xt_dccp_info *info; - - info = (const struct xt_dccp_info *)matchinfo; - - return ip->proto == IPPROTO_DCCP - && !(ip->invflags & XT_INV_PROTO) - && matchsize == XT_ALIGN(sizeof(struct xt_dccp_info)) - && !(info->flags & ~XT_DCCP_VALID_FLAGS) - && !(info->invflags & ~XT_DCCP_VALID_FLAGS) - && !(info->invflags & ~info->flags); -} - - -static struct xt_match dccp_match = +static struct ipt_match dccp_match = { .name = "dccp", .match = &match, .checkentry = &checkentry, .me = THIS_MODULE, }; -static struct xt_match dccp6_match = -{ - .name = "dccp", - .match = &match, - .checkentry = &checkentry6, - .me = THIS_MODULE, -}; - static int __init init(void) { @@ -193,29 +154,23 @@ static int __init init(void) dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL); if (!dccp_optbuf) return -ENOMEM; - ret = xt_register_match(AF_INET, &dccp_match); + ret = ipt_register_match(&dccp_match); if (ret) - goto out_kfree; - ret = xt_register_match(AF_INET6, &dccp6_match); - if (ret) - goto out_unreg; - - return ret; - -out_unreg: - xt_unregister_match(AF_INET, &dccp_match); -out_kfree: - kfree(dccp_optbuf); + kfree(dccp_optbuf); return ret; } static void __exit fini(void) { - xt_unregister_match(AF_INET6, &dccp6_match); - xt_unregister_match(AF_INET, &dccp_match); + ipt_unregister_match(&dccp_match); kfree(dccp_optbuf); } module_init(init); module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("Match for DCCP protocol packets"); + diff --git a/trunk/net/ipv4/netfilter/ipt_dscp.c b/trunk/net/ipv4/netfilter/ipt_dscp.c index 92063b4f8602..5df52a64a5d4 100644 --- a/trunk/net/ipv4/netfilter/ipt_dscp.c +++ b/trunk/net/ipv4/netfilter/ipt_dscp.c @@ -21,7 +21,7 @@ MODULE_LICENSE("GPL"); static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, - int offset, unsigned int protoff, int *hotdrop) + int offset, int *hotdrop) { const struct ipt_dscp_info *info = matchinfo; const struct iphdr *iph = skb->nh.iph; @@ -31,7 +31,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; } -static int checkentry(const char *tablename, const void *ip, +static int checkentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { diff --git a/trunk/net/ipv4/netfilter/ipt_ecn.c b/trunk/net/ipv4/netfilter/ipt_ecn.c index e68b0c7981f0..b6f7181e89cc 100644 --- a/trunk/net/ipv4/netfilter/ipt_ecn.c +++ b/trunk/net/ipv4/netfilter/ipt_ecn.c @@ -67,7 +67,7 @@ static inline int match_tcp(const struct sk_buff *skb, static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, - int offset, unsigned int protoff, int *hotdrop) + int offset, int *hotdrop) { const struct ipt_ecn_info *info = matchinfo; @@ -85,12 +85,11 @@ static int match(const struct sk_buff *skb, const struct net_device *in, return 1; } -static int checkentry(const char *tablename, const void *ip_void, +static int checkentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { const struct ipt_ecn_info *info = matchinfo; - const struct ipt_ip *ip = ip_void; if (matchsize != IPT_ALIGN(sizeof(struct ipt_ecn_info))) return 0; diff --git a/trunk/net/ipv4/netfilter/ipt_esp.c b/trunk/net/ipv4/netfilter/ipt_esp.c index 9de191a8162d..e1d0dd31e117 100644 --- a/trunk/net/ipv4/netfilter/ipt_esp.c +++ b/trunk/net/ipv4/netfilter/ipt_esp.c @@ -42,7 +42,6 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { struct ip_esp_hdr _esp, *eh; @@ -52,7 +51,7 @@ match(const struct sk_buff *skb, if (offset) return 0; - eh = skb_header_pointer(skb, protoff, + eh = skb_header_pointer(skb, skb->nh.iph->ihl * 4, sizeof(_esp), &_esp); if (eh == NULL) { /* We've been asked to examine this packet, and we @@ -71,13 +70,12 @@ match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *ip_void, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchinfosize, unsigned int hook_mask) { const struct ipt_esp *espinfo = matchinfo; - const struct ipt_ip *ip = ip_void; /* Must specify proto == ESP, and no unknown invflags */ if (ip->proto != IPPROTO_ESP || (ip->invflags & IPT_INV_PROTO)) { diff --git a/trunk/net/ipv4/netfilter/ipt_hashlimit.c b/trunk/net/ipv4/netfilter/ipt_hashlimit.c index 4fe48c1bd5f3..2dd1cccbdab9 100644 --- a/trunk/net/ipv4/netfilter/ipt_hashlimit.c +++ b/trunk/net/ipv4/netfilter/ipt_hashlimit.c @@ -429,7 +429,6 @@ hashlimit_match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { struct ipt_hashlimit_info *r = @@ -505,7 +504,7 @@ hashlimit_match(const struct sk_buff *skb, static int hashlimit_checkentry(const char *tablename, - const void *inf, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) diff --git a/trunk/net/netfilter/xt_helper.c b/trunk/net/ipv4/netfilter/ipt_helper.c similarity index 72% rename from trunk/net/netfilter/xt_helper.c rename to trunk/net/ipv4/netfilter/ipt_helper.c index 38b6715e1db4..aef649e393af 100644 --- a/trunk/net/netfilter/xt_helper.c +++ b/trunk/net/ipv4/netfilter/ipt_helper.c @@ -13,6 +13,7 @@ #include #include #include +#include #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) #include #include @@ -22,14 +23,12 @@ #include #include #endif -#include -#include +#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Martin Josefsson "); MODULE_DESCRIPTION("iptables helper match module"); -MODULE_ALIAS("ipt_helper"); -MODULE_ALIAS("ip6t_helper"); #if 0 #define DEBUGP printk @@ -44,28 +43,27 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_helper_info *info = matchinfo; + const struct ipt_helper_info *info = matchinfo; struct ip_conntrack *ct; enum ip_conntrack_info ctinfo; int ret = info->invert; ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); if (!ct) { - DEBUGP("xt_helper: Eek! invalid conntrack?\n"); + DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); return ret; } if (!ct->master) { - DEBUGP("xt_helper: conntrack %p has no master\n", ct); + DEBUGP("ipt_helper: conntrack %p has no master\n", ct); return ret; } read_lock_bh(&ip_conntrack_lock); if (!ct->master->helper) { - DEBUGP("xt_helper: master ct %p has no helper\n", + DEBUGP("ipt_helper: master ct %p has no helper\n", exp->expectant); goto out_unlock; } @@ -91,28 +89,27 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_helper_info *info = matchinfo; + const struct ipt_helper_info *info = matchinfo; struct nf_conn *ct; enum ip_conntrack_info ctinfo; int ret = info->invert; ct = nf_ct_get((struct sk_buff *)skb, &ctinfo); if (!ct) { - DEBUGP("xt_helper: Eek! invalid conntrack?\n"); + DEBUGP("ipt_helper: Eek! invalid conntrack?\n"); return ret; } if (!ct->master) { - DEBUGP("xt_helper: conntrack %p has no master\n", ct); + DEBUGP("ipt_helper: conntrack %p has no master\n", ct); return ret; } read_lock_bh(&nf_conntrack_lock); if (!ct->master->helper) { - DEBUGP("xt_helper: master ct %p has no helper\n", + DEBUGP("ipt_helper: master ct %p has no helper\n", exp->expectant); goto out_unlock; } @@ -132,29 +129,23 @@ match(const struct sk_buff *skb, #endif static int check(const char *tablename, - const void *inf, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - struct xt_helper_info *info = matchinfo; + struct ipt_helper_info *info = matchinfo; info->name[29] = '\0'; /* verify size */ - if (matchsize != XT_ALIGN(sizeof(struct xt_helper_info))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_helper_info))) return 0; return 1; } -static struct xt_match helper_match = { - .name = "helper", - .match = &match, - .checkentry = &check, - .me = THIS_MODULE, -}; -static struct xt_match helper6_match = { +static struct ipt_match helper_match = { .name = "helper", .match = &match, .checkentry = &check, @@ -163,24 +154,13 @@ static struct xt_match helper6_match = { static int __init init(void) { - int ret; - need_conntrack(); - - ret = xt_register_match(AF_INET, &helper_match); - if (ret < 0) - return ret; - - ret = xt_register_match(AF_INET6, &helper6_match); - if (ret < 0) - xt_unregister_match(AF_INET, &helper_match); - - return ret; + need_ip_conntrack(); + return ipt_register_match(&helper_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &helper_match); - xt_unregister_match(AF_INET6, &helper6_match); + ipt_unregister_match(&helper_match); } module_init(init); diff --git a/trunk/net/ipv4/netfilter/ipt_iprange.c b/trunk/net/ipv4/netfilter/ipt_iprange.c index 13fb16fb7892..b835b7b2e560 100644 --- a/trunk/net/ipv4/netfilter/ipt_iprange.c +++ b/trunk/net/ipv4/netfilter/ipt_iprange.c @@ -28,7 +28,7 @@ match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, - int offset, unsigned int protoff, int *hotdrop) + int offset, int *hotdrop) { const struct ipt_iprange_info *info = matchinfo; const struct iphdr *iph = skb->nh.iph; @@ -63,7 +63,7 @@ match(const struct sk_buff *skb, } static int check(const char *tablename, - const void *inf, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_length.c b/trunk/net/ipv4/netfilter/ipt_length.c new file mode 100644 index 000000000000..4eabcfbda9d1 --- /dev/null +++ b/trunk/net/ipv4/netfilter/ipt_length.c @@ -0,0 +1,64 @@ +/* Kernel module to match packet length. */ +/* (C) 1999-2001 James Morris + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include +#include + +MODULE_AUTHOR("James Morris "); +MODULE_DESCRIPTION("IP tables packet length matching module"); +MODULE_LICENSE("GPL"); + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop) +{ + const struct ipt_length_info *info = matchinfo; + u_int16_t pktlen = ntohs(skb->nh.iph->tot_len); + + return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; +} + +static int +checkentry(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (matchsize != IPT_ALIGN(sizeof(struct ipt_length_info))) + return 0; + + return 1; +} + +static struct ipt_match length_match = { + .name = "length", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_match(&length_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&length_match); +} + +module_init(init); +module_exit(fini); diff --git a/trunk/net/netfilter/xt_limit.c b/trunk/net/ipv4/netfilter/ipt_limit.c similarity index 78% rename from trunk/net/netfilter/xt_limit.c rename to trunk/net/ipv4/netfilter/ipt_limit.c index 15e40506bc3a..0c24dcc703a5 100644 --- a/trunk/net/netfilter/xt_limit.c +++ b/trunk/net/ipv4/netfilter/ipt_limit.c @@ -18,14 +18,12 @@ #include #include -#include -#include +#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Herve Eychenne "); MODULE_DESCRIPTION("iptables rate limit match"); -MODULE_ALIAS("ipt_limit"); -MODULE_ALIAS("ip6t_limit"); /* The algorithm used is the Simple Token Bucket Filter (TBF) * see net/sched/sch_tbf.c in the linux source tree @@ -70,10 +68,9 @@ ipt_limit_match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - struct xt_rateinfo *r = ((struct xt_rateinfo *)matchinfo)->master; + struct ipt_rateinfo *r = ((struct ipt_rateinfo *)matchinfo)->master; unsigned long now = jiffies; spin_lock_bh(&limit_lock); @@ -99,32 +96,32 @@ user2credits(u_int32_t user) /* If multiplying would overflow... */ if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) /* Divide first. */ - return (user / XT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; + return (user / IPT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; - return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; + return (user * HZ * CREDITS_PER_JIFFY) / IPT_LIMIT_SCALE; } static int ipt_limit_checkentry(const char *tablename, - const void *inf, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - struct xt_rateinfo *r = matchinfo; + struct ipt_rateinfo *r = matchinfo; - if (matchsize != XT_ALIGN(sizeof(struct xt_rateinfo))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_rateinfo))) return 0; /* Check for overflow. */ if (r->burst == 0 || user2credits(r->avg * r->burst) < user2credits(r->avg)) { - printk("Overflow in xt_limit, try lower: %u/%u\n", + printk("Overflow in ipt_limit, try lower: %u/%u\n", r->avg, r->burst); return 0; } - /* User avg in seconds * XT_LIMIT_SCALE: convert to jiffies * + /* User avg in seconds * IPT_LIMIT_SCALE: convert to jiffies * 128. */ r->prev = jiffies; r->credit = user2credits(r->avg * r->burst); /* Credits full. */ @@ -137,13 +134,7 @@ ipt_limit_checkentry(const char *tablename, return 1; } -static struct xt_match ipt_limit_reg = { - .name = "limit", - .match = ipt_limit_match, - .checkentry = ipt_limit_checkentry, - .me = THIS_MODULE, -}; -static struct xt_match limit6_reg = { +static struct ipt_match ipt_limit_reg = { .name = "limit", .match = ipt_limit_match, .checkentry = ipt_limit_checkentry, @@ -152,23 +143,14 @@ static struct xt_match limit6_reg = { static int __init init(void) { - int ret; - - ret = xt_register_match(AF_INET, &ipt_limit_reg); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &limit6_reg); - if (ret) - xt_unregister_match(AF_INET, &ipt_limit_reg); - - return ret; + if (ipt_register_match(&ipt_limit_reg)) + return -EINVAL; + return 0; } static void __exit fini(void) { - xt_unregister_match(AF_INET, &ipt_limit_reg); - xt_unregister_match(AF_INET6, &limit6_reg); + ipt_unregister_match(&ipt_limit_reg); } module_init(init); diff --git a/trunk/net/netfilter/xt_mac.c b/trunk/net/ipv4/netfilter/ipt_mac.c similarity index 65% rename from trunk/net/netfilter/xt_mac.c rename to trunk/net/ipv4/netfilter/ipt_mac.c index 0461dcb5fc7a..1b9bb4559f80 100644 --- a/trunk/net/netfilter/xt_mac.c +++ b/trunk/net/ipv4/netfilter/ipt_mac.c @@ -13,15 +13,12 @@ #include #include -#include -#include -#include +#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Netfilter Core Team "); MODULE_DESCRIPTION("iptables mac matching module"); -MODULE_ALIAS("ipt_mac"); -MODULE_ALIAS("ip6t_mac"); static int match(const struct sk_buff *skb, @@ -29,10 +26,9 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_mac_info *info = matchinfo; + const struct ipt_mac_info *info = matchinfo; /* Is mac pointer valid? */ return (skb->mac.raw >= skb->head @@ -44,7 +40,7 @@ match(const struct sk_buff *skb, static int ipt_mac_checkentry(const char *tablename, - const void *inf, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) @@ -53,23 +49,17 @@ ipt_mac_checkentry(const char *tablename, if (hook_mask & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD))) { - printk("xt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); + printk("ipt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); return 0; } - if (matchsize != XT_ALIGN(sizeof(struct xt_mac_info))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mac_info))) return 0; return 1; } -static struct xt_match mac_match = { - .name = "mac", - .match = &match, - .checkentry = &ipt_mac_checkentry, - .me = THIS_MODULE, -}; -static struct xt_match mac6_match = { +static struct ipt_match mac_match = { .name = "mac", .match = &match, .checkentry = &ipt_mac_checkentry, @@ -78,22 +68,12 @@ static struct xt_match mac6_match = { static int __init init(void) { - int ret; - ret = xt_register_match(AF_INET, &mac_match); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &mac6_match); - if (ret) - xt_unregister_match(AF_INET, &mac_match); - - return ret; + return ipt_register_match(&mac_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &mac_match); - xt_unregister_match(AF_INET6, &mac6_match); + ipt_unregister_match(&mac_match); } module_init(init); diff --git a/trunk/net/netfilter/xt_mark.c b/trunk/net/ipv4/netfilter/ipt_mark.c similarity index 60% rename from trunk/net/netfilter/xt_mark.c rename to trunk/net/ipv4/netfilter/ipt_mark.c index 2a0ac62b72c8..00bef6cdd3f8 100644 --- a/trunk/net/netfilter/xt_mark.c +++ b/trunk/net/ipv4/netfilter/ipt_mark.c @@ -10,14 +10,12 @@ #include #include -#include -#include +#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marc Boucher "); MODULE_DESCRIPTION("iptables mark matching module"); -MODULE_ALIAS("ipt_mark"); -MODULE_ALIAS("ip6t_mark"); static int match(const struct sk_buff *skb, @@ -25,24 +23,23 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_mark_info *info = matchinfo; + const struct ipt_mark_info *info = matchinfo; return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; } static int checkentry(const char *tablename, - const void *entry, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - struct xt_mark_info *minfo = (struct xt_mark_info *) matchinfo; + struct ipt_mark_info *minfo = (struct ipt_mark_info *) matchinfo; - if (matchsize != XT_ALIGN(sizeof(struct xt_mark_info))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_mark_info))) return 0; if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { @@ -53,14 +50,7 @@ checkentry(const char *tablename, return 1; } -static struct xt_match mark_match = { - .name = "mark", - .match = &match, - .checkentry = &checkentry, - .me = THIS_MODULE, -}; - -static struct xt_match mark6_match = { +static struct ipt_match mark_match = { .name = "mark", .match = &match, .checkentry = &checkentry, @@ -69,22 +59,12 @@ static struct xt_match mark6_match = { static int __init init(void) { - int ret; - ret = xt_register_match(AF_INET, &mark_match); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &mark6_match); - if (ret) - xt_unregister_match(AF_INET, &mark_match); - - return ret; + return ipt_register_match(&mark_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &mark_match); - xt_unregister_match(AF_INET6, &mark6_match); + ipt_unregister_match(&mark_match); } module_init(init); diff --git a/trunk/net/ipv4/netfilter/ipt_multiport.c b/trunk/net/ipv4/netfilter/ipt_multiport.c index 2d52326553f1..99e8188162e2 100644 --- a/trunk/net/ipv4/netfilter/ipt_multiport.c +++ b/trunk/net/ipv4/netfilter/ipt_multiport.c @@ -97,7 +97,6 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { u16 _ports[2], *pptr; @@ -106,7 +105,7 @@ match(const struct sk_buff *skb, if (offset) return 0; - pptr = skb_header_pointer(skb, protoff, + pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, sizeof(_ports), _ports); if (pptr == NULL) { /* We've been asked to examine this packet, and we @@ -129,7 +128,6 @@ match_v1(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { u16 _ports[2], *pptr; @@ -138,7 +136,7 @@ match_v1(const struct sk_buff *skb, if (offset) return 0; - pptr = skb_header_pointer(skb, protoff, + pptr = skb_header_pointer(skb, skb->nh.iph->ihl * 4, sizeof(_ports), _ports); if (pptr == NULL) { /* We've been asked to examine this packet, and we @@ -156,7 +154,7 @@ match_v1(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) @@ -166,7 +164,7 @@ checkentry(const char *tablename, static int checkentry_v1(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_owner.c b/trunk/net/ipv4/netfilter/ipt_owner.c index 4843d0c9734f..0cee2862ed85 100644 --- a/trunk/net/ipv4/netfilter/ipt_owner.c +++ b/trunk/net/ipv4/netfilter/ipt_owner.c @@ -27,7 +27,6 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { const struct ipt_owner_info *info = matchinfo; @@ -52,7 +51,7 @@ match(const struct sk_buff *skb, static int checkentry(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_physdev.c b/trunk/net/ipv4/netfilter/ipt_physdev.c new file mode 100644 index 000000000000..03f554857a4d --- /dev/null +++ b/trunk/net/ipv4/netfilter/ipt_physdev.c @@ -0,0 +1,135 @@ +/* Kernel module to match the bridge port in and + * out device for IP packets coming into contact with a bridge. */ + +/* (C) 2001-2003 Bart De Schuymer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#define MATCH 1 +#define NOMATCH 0 + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Bart De Schuymer "); +MODULE_DESCRIPTION("iptables bridge physical device match module"); + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop) +{ + int i; + static const char nulldevname[IFNAMSIZ]; + const struct ipt_physdev_info *info = matchinfo; + unsigned int ret; + const char *indev, *outdev; + struct nf_bridge_info *nf_bridge; + + /* Not a bridged IP packet or no info available yet: + * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if + * the destination device will be a bridge. */ + if (!(nf_bridge = skb->nf_bridge)) { + /* Return MATCH if the invert flags of the used options are on */ + if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && + !(info->invert & IPT_PHYSDEV_OP_BRIDGED)) + return NOMATCH; + if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) && + !(info->invert & IPT_PHYSDEV_OP_ISIN)) + return NOMATCH; + if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) && + !(info->invert & IPT_PHYSDEV_OP_ISOUT)) + return NOMATCH; + if ((info->bitmask & IPT_PHYSDEV_OP_IN) && + !(info->invert & IPT_PHYSDEV_OP_IN)) + return NOMATCH; + if ((info->bitmask & IPT_PHYSDEV_OP_OUT) && + !(info->invert & IPT_PHYSDEV_OP_OUT)) + return NOMATCH; + return MATCH; + } + + /* This only makes sense in the FORWARD and POSTROUTING chains */ + if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && + (!!(nf_bridge->mask & BRNF_BRIDGED) ^ + !(info->invert & IPT_PHYSDEV_OP_BRIDGED))) + return NOMATCH; + + if ((info->bitmask & IPT_PHYSDEV_OP_ISIN && + (!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) || + (info->bitmask & IPT_PHYSDEV_OP_ISOUT && + (!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT)))) + return NOMATCH; + + if (!(info->bitmask & IPT_PHYSDEV_OP_IN)) + goto match_outdev; + indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; + for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { + ret |= (((const unsigned int *)indev)[i] + ^ ((const unsigned int *)info->physindev)[i]) + & ((const unsigned int *)info->in_mask)[i]; + } + + if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN)) + return NOMATCH; + +match_outdev: + if (!(info->bitmask & IPT_PHYSDEV_OP_OUT)) + return MATCH; + outdev = nf_bridge->physoutdev ? + nf_bridge->physoutdev->name : nulldevname; + for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { + ret |= (((const unsigned int *)outdev)[i] + ^ ((const unsigned int *)info->physoutdev)[i]) + & ((const unsigned int *)info->out_mask)[i]; + } + + return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT); +} + +static int +checkentry(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + const struct ipt_physdev_info *info = matchinfo; + + if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info))) + return 0; + if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) || + info->bitmask & ~IPT_PHYSDEV_OP_MASK) + return 0; + return 1; +} + +static struct ipt_match physdev_match = { + .name = "physdev", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ipt_register_match(&physdev_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&physdev_match); +} + +module_init(init); +module_exit(fini); diff --git a/trunk/net/netfilter/xt_pkttype.c b/trunk/net/ipv4/netfilter/ipt_pkttype.c similarity index 55% rename from trunk/net/netfilter/xt_pkttype.c rename to trunk/net/ipv4/netfilter/ipt_pkttype.c index ab1b2630f97d..8ddb1dc5e5ae 100644 --- a/trunk/net/netfilter/xt_pkttype.c +++ b/trunk/net/ipv4/netfilter/ipt_pkttype.c @@ -10,72 +10,60 @@ #include #include -#include -#include +#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Michal Ludvig "); MODULE_DESCRIPTION("IP tables match to match on linklayer packet type"); -MODULE_ALIAS("ipt_pkttype"); -MODULE_ALIAS("ip6t_pkttype"); static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_pkttype_info *info = matchinfo; + const struct ipt_pkttype_info *info = matchinfo; - return (skb->pkt_type == info->pkttype) ^ info->invert; + return (skb->pkt_type == info->pkttype) ^ info->invert; } static int checkentry(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - if (matchsize != XT_ALIGN(sizeof(struct xt_pkttype_info))) +/* + if (hook_mask + & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) + | (1 << NF_IP_FORWARD))) { + printk("ipt_pkttype: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n"); + return 0; + } +*/ + if (matchsize != IPT_ALIGN(sizeof(struct ipt_pkttype_info))) return 0; return 1; } -static struct xt_match pkttype_match = { +static struct ipt_match pkttype_match = { .name = "pkttype", .match = &match, .checkentry = &checkentry, .me = THIS_MODULE, }; -static struct xt_match pkttype6_match = { - .name = "pkttype", - .match = &match, - .checkentry = &checkentry, - .me = THIS_MODULE, -}; - static int __init init(void) { - int ret; - ret = xt_register_match(AF_INET, &pkttype_match); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &pkttype6_match); - if (ret) - xt_unregister_match(AF_INET, &pkttype_match); - - return ret; + return ipt_register_match(&pkttype_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &pkttype_match); - xt_unregister_match(AF_INET6, &pkttype6_match); + ipt_unregister_match(&pkttype_match); } module_init(init); diff --git a/trunk/net/netfilter/xt_realm.c b/trunk/net/ipv4/netfilter/ipt_realm.c similarity index 70% rename from trunk/net/netfilter/xt_realm.c rename to trunk/net/ipv4/netfilter/ipt_realm.c index 2b7e1781d34d..54a6897ebaa6 100644 --- a/trunk/net/netfilter/xt_realm.c +++ b/trunk/net/ipv4/netfilter/ipt_realm.c @@ -14,14 +14,12 @@ #include #include -#include -#include -#include +#include +#include MODULE_AUTHOR("Sampsa Ranta "); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("X_tables realm match"); -MODULE_ALIAS("ipt_realm"); +MODULE_DESCRIPTION("iptables realm match"); static int match(const struct sk_buff *skb, @@ -29,17 +27,16 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_realm_info *info = matchinfo; + const struct ipt_realm_info *info = matchinfo; struct dst_entry *dst = skb->dst; return (info->id == (dst->tclassid & info->mask)) ^ info->invert; } static int check(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) @@ -47,18 +44,18 @@ static int check(const char *tablename, if (hook_mask & ~((1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN))) { - printk("xt_realm: only valid for POST_ROUTING, LOCAL_OUT, " + printk("ipt_realm: only valid for POST_ROUTING, LOCAL_OUT, " "LOCAL_IN or FORWARD.\n"); return 0; } - if (matchsize != XT_ALIGN(sizeof(struct xt_realm_info))) { - printk("xt_realm: invalid matchsize.\n"); + if (matchsize != IPT_ALIGN(sizeof(struct ipt_realm_info))) { + printk("ipt_realm: invalid matchsize.\n"); return 0; } return 1; } -static struct xt_match realm_match = { +static struct ipt_match realm_match = { .name = "realm", .match = match, .checkentry = check, @@ -67,12 +64,12 @@ static struct xt_match realm_match = { static int __init init(void) { - return xt_register_match(AF_INET, &realm_match); + return ipt_register_match(&realm_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &realm_match); + ipt_unregister_match(&realm_match); } module_init(init); diff --git a/trunk/net/ipv4/netfilter/ipt_recent.c b/trunk/net/ipv4/netfilter/ipt_recent.c index 44611d6d14f5..5ddccb18c65e 100644 --- a/trunk/net/ipv4/netfilter/ipt_recent.c +++ b/trunk/net/ipv4/netfilter/ipt_recent.c @@ -104,7 +104,6 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop); /* Function to hash a given address into the hash table of table_size size */ @@ -318,7 +317,7 @@ static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned skb->nh.iph->daddr = 0; /* Clear ttl since we have no way of knowing it */ skb->nh.iph->ttl = 0; - match(skb,NULL,NULL,info,0,0,NULL); + match(skb,NULL,NULL,info,0,NULL); kfree(skb->nh.iph); out_free_skb: @@ -358,7 +357,6 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { int pkt_count, hits_found, ans; @@ -656,7 +654,7 @@ match(const struct sk_buff *skb, */ static int checkentry(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) diff --git a/trunk/net/netfilter/xt_sctp.c b/trunk/net/ipv4/netfilter/ipt_sctp.c similarity index 62% rename from trunk/net/netfilter/xt_sctp.c rename to trunk/net/ipv4/netfilter/ipt_sctp.c index 10fbfc5ba758..fe2b327bcaa4 100644 --- a/trunk/net/netfilter/xt_sctp.c +++ b/trunk/net/ipv4/netfilter/ipt_sctp.c @@ -1,18 +1,10 @@ #include #include #include -#include #include -#include -#include #include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kiran Kumar Immidi"); -MODULE_DESCRIPTION("Match for SCTP protocol packets"); -MODULE_ALIAS("ipt_sctp"); +#include #ifdef DEBUG_SCTP #define duprintf(format, args...) printk(format , ## args) @@ -24,7 +16,7 @@ MODULE_ALIAS("ipt_sctp"); || (!!((invflag) & (option)) ^ (cond))) static int -match_flags(const struct xt_sctp_flag_info *flag_info, +match_flags(const struct ipt_sctp_flag_info *flag_info, const int flag_count, u_int8_t chunktype, u_int8_t chunkflags) @@ -40,15 +32,15 @@ match_flags(const struct xt_sctp_flag_info *flag_info, return 1; } -static inline int +static int match_packet(const struct sk_buff *skb, - unsigned int offset, const u_int32_t *chunkmap, int chunk_match_type, - const struct xt_sctp_flag_info *flag_info, + const struct ipt_sctp_flag_info *flag_info, const int flag_count, int *hotdrop) { + int offset; u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; sctp_chunkhdr_t _sch, *sch; @@ -60,6 +52,7 @@ match_packet(const struct sk_buff *skb, SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); } + offset = skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t); do { sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); if (sch == NULL) { @@ -125,20 +118,19 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_sctp_info *info; + const struct ipt_sctp_info *info; sctp_sctphdr_t _sh, *sh; - info = (const struct xt_sctp_info *)matchinfo; + info = (const struct ipt_sctp_info *)matchinfo; if (offset) { duprintf("Dropping non-first fragment.. FIXME\n"); return 0; } - sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh); + sh = skb_header_pointer(skb, skb->nh.iph->ihl*4, sizeof(_sh), &_sh); if (sh == NULL) { duprintf("Dropping evil TCP offset=0 tinygram.\n"); *hotdrop = 1; @@ -148,103 +140,64 @@ match(const struct sk_buff *skb, return SCCHECK(((ntohs(sh->source) >= info->spts[0]) && (ntohs(sh->source) <= info->spts[1])), - XT_SCTP_SRC_PORTS, info->flags, info->invflags) + IPT_SCTP_SRC_PORTS, info->flags, info->invflags) && SCCHECK(((ntohs(sh->dest) >= info->dpts[0]) && (ntohs(sh->dest) <= info->dpts[1])), - XT_SCTP_DEST_PORTS, info->flags, info->invflags) - && SCCHECK(match_packet(skb, protoff, - info->chunkmap, info->chunk_match_type, + IPT_SCTP_DEST_PORTS, info->flags, info->invflags) + && SCCHECK(match_packet(skb, info->chunkmap, info->chunk_match_type, info->flag_info, info->flag_count, hotdrop), - XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); + IPT_SCTP_CHUNK_TYPES, info->flags, info->invflags); } static int checkentry(const char *tablename, - const void *inf, - void *matchinfo, - unsigned int matchsize, - unsigned int hook_mask) -{ - const struct xt_sctp_info *info; - const struct ipt_ip *ip = inf; - - info = (const struct xt_sctp_info *)matchinfo; - - return ip->proto == IPPROTO_SCTP - && !(ip->invflags & XT_INV_PROTO) - && matchsize == XT_ALIGN(sizeof(struct xt_sctp_info)) - && !(info->flags & ~XT_SCTP_VALID_FLAGS) - && !(info->invflags & ~XT_SCTP_VALID_FLAGS) - && !(info->invflags & ~info->flags) - && ((!(info->flags & XT_SCTP_CHUNK_TYPES)) || - (info->chunk_match_type & - (SCTP_CHUNK_MATCH_ALL - | SCTP_CHUNK_MATCH_ANY - | SCTP_CHUNK_MATCH_ONLY))); -} - -static int -checkentry6(const char *tablename, - const void *inf, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - const struct xt_sctp_info *info; - const struct ip6t_ip6 *ip = inf; + const struct ipt_sctp_info *info; - info = (const struct xt_sctp_info *)matchinfo; + info = (const struct ipt_sctp_info *)matchinfo; return ip->proto == IPPROTO_SCTP - && !(ip->invflags & XT_INV_PROTO) - && matchsize == XT_ALIGN(sizeof(struct xt_sctp_info)) - && !(info->flags & ~XT_SCTP_VALID_FLAGS) - && !(info->invflags & ~XT_SCTP_VALID_FLAGS) + && !(ip->invflags & IPT_INV_PROTO) + && matchsize == IPT_ALIGN(sizeof(struct ipt_sctp_info)) + && !(info->flags & ~IPT_SCTP_VALID_FLAGS) + && !(info->invflags & ~IPT_SCTP_VALID_FLAGS) && !(info->invflags & ~info->flags) - && ((!(info->flags & XT_SCTP_CHUNK_TYPES)) || + && ((!(info->flags & IPT_SCTP_CHUNK_TYPES)) || (info->chunk_match_type & (SCTP_CHUNK_MATCH_ALL | SCTP_CHUNK_MATCH_ANY | SCTP_CHUNK_MATCH_ONLY))); } - -static struct xt_match sctp_match = +static struct ipt_match sctp_match = { + .list = { NULL, NULL}, .name = "sctp", .match = &match, .checkentry = &checkentry, - .me = THIS_MODULE -}; -static struct xt_match sctp6_match = -{ - .name = "sctp", - .match = &match, - .checkentry = &checkentry6, + .destroy = NULL, .me = THIS_MODULE }; - static int __init init(void) { - int ret; - ret = xt_register_match(AF_INET, &sctp_match); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &sctp6_match); - if (ret) - xt_unregister_match(AF_INET, &sctp_match); - - return ret; + return ipt_register_match(&sctp_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET6, &sctp6_match); - xt_unregister_match(AF_INET, &sctp_match); + ipt_unregister_match(&sctp_match); } module_init(init); module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kiran Kumar Immidi"); +MODULE_DESCRIPTION("Match for SCTP protocol packets"); + diff --git a/trunk/net/netfilter/xt_state.c b/trunk/net/ipv4/netfilter/ipt_state.c similarity index 53% rename from trunk/net/netfilter/xt_state.c rename to trunk/net/ipv4/netfilter/ipt_state.c index 39ce808d40ef..4d7f16b70cec 100644 --- a/trunk/net/netfilter/xt_state.c +++ b/trunk/net/ipv4/netfilter/ipt_state.c @@ -1,7 +1,7 @@ /* Kernel module to match connection tracking information. */ /* (C) 1999-2001 Paul `Rusty' Russell - * (C) 2002-2005 Netfilter Core Team + * (C) 2002-2004 Netfilter Core Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -11,14 +11,12 @@ #include #include #include -#include -#include +#include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Rusty Russell "); -MODULE_DESCRIPTION("ip[6]_tables connection tracking state match module"); -MODULE_ALIAS("ipt_state"); -MODULE_ALIAS("ip6t_state"); +MODULE_DESCRIPTION("iptables connection tracking state match module"); static int match(const struct sk_buff *skb, @@ -26,43 +24,35 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_state_info *sinfo = matchinfo; + const struct ipt_state_info *sinfo = matchinfo; enum ip_conntrack_info ctinfo; unsigned int statebit; if (nf_ct_is_untracked(skb)) - statebit = XT_STATE_UNTRACKED; + statebit = IPT_STATE_UNTRACKED; else if (!nf_ct_get_ctinfo(skb, &ctinfo)) - statebit = XT_STATE_INVALID; + statebit = IPT_STATE_INVALID; else - statebit = XT_STATE_BIT(ctinfo); + statebit = IPT_STATE_BIT(ctinfo); return (sinfo->statemask & statebit); } static int check(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - if (matchsize != XT_ALIGN(sizeof(struct xt_state_info))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_state_info))) return 0; return 1; } -static struct xt_match state_match = { - .name = "state", - .match = &match, - .checkentry = &check, - .me = THIS_MODULE, -}; - -static struct xt_match state6_match = { +static struct ipt_match state_match = { .name = "state", .match = &match, .checkentry = &check, @@ -71,25 +61,13 @@ static struct xt_match state6_match = { static int __init init(void) { - int ret; - - need_conntrack(); - - ret = xt_register_match(AF_INET, &state_match); - if (ret < 0) - return ret; - - ret = xt_register_match(AF_INET6, &state6_match); - if (ret < 0) - xt_unregister_match(AF_INET,&state_match); - - return ret; + need_ip_conntrack(); + return ipt_register_match(&state_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &state_match); - xt_unregister_match(AF_INET6, &state6_match); + ipt_unregister_match(&state_match); } module_init(init); diff --git a/trunk/net/netfilter/xt_string.c b/trunk/net/ipv4/netfilter/ipt_string.c similarity index 66% rename from trunk/net/netfilter/xt_string.c rename to trunk/net/ipv4/netfilter/ipt_string.c index 7c7d5c8807d6..b5def204d798 100644 --- a/trunk/net/netfilter/xt_string.c +++ b/trunk/net/ipv4/netfilter/ipt_string.c @@ -11,26 +11,23 @@ #include #include #include -#include -#include +#include +#include #include MODULE_AUTHOR("Pablo Neira Ayuso "); MODULE_DESCRIPTION("IP tables string match module"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ipt_string"); -MODULE_ALIAS("ip6t_string"); static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { struct ts_state state; - struct xt_string_info *conf = (struct xt_string_info *) matchinfo; + struct ipt_string_info *conf = (struct ipt_string_info *) matchinfo; memset(&state, 0, sizeof(struct ts_state)); @@ -39,18 +36,18 @@ static int match(const struct sk_buff *skb, != UINT_MAX) && !conf->invert; } -#define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m) +#define STRING_TEXT_PRIV(m) ((struct ipt_string_info *) m) static int checkentry(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - struct xt_string_info *conf = matchinfo; + struct ipt_string_info *conf = matchinfo; struct ts_config *ts_conf; - if (matchsize != XT_ALIGN(sizeof(struct xt_string_info))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_string_info))) return 0; /* Damn, can't handle this case properly with iptables... */ @@ -72,14 +69,7 @@ static void destroy(void *matchinfo, unsigned int matchsize) textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); } -static struct xt_match string_match = { - .name = "string", - .match = match, - .checkentry = checkentry, - .destroy = destroy, - .me = THIS_MODULE -}; -static struct xt_match string6_match = { +static struct ipt_match string_match = { .name = "string", .match = match, .checkentry = checkentry, @@ -89,22 +79,12 @@ static struct xt_match string6_match = { static int __init init(void) { - int ret; - - ret = xt_register_match(AF_INET, &string_match); - if (ret) - return ret; - ret = xt_register_match(AF_INET6, &string6_match); - if (ret) - xt_unregister_match(AF_INET, &string_match); - - return ret; + return ipt_register_match(&string_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &string_match); - xt_unregister_match(AF_INET6, &string6_match); + ipt_unregister_match(&string_match); } module_init(init); diff --git a/trunk/net/netfilter/xt_tcpmss.c b/trunk/net/ipv4/netfilter/ipt_tcpmss.c similarity index 59% rename from trunk/net/netfilter/xt_tcpmss.c rename to trunk/net/ipv4/netfilter/ipt_tcpmss.c index acf7f533e9f1..4dc9b16ab4a3 100644 --- a/trunk/net/netfilter/xt_tcpmss.c +++ b/trunk/net/ipv4/netfilter/ipt_tcpmss.c @@ -1,7 +1,6 @@ /* Kernel module to match TCP MSS values. */ /* Copyright (C) 2000 Marc Boucher - * Portions (C) 2005 by Harald Welte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -12,24 +11,19 @@ #include #include -#include -#include - +#include #include -#include #define TH_SYN 0x02 MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marc Boucher "); MODULE_DESCRIPTION("iptables TCP MSS match module"); -MODULE_ALIAS("ipt_tcpmss"); /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */ static inline int mssoption_match(u_int16_t min, u_int16_t max, const struct sk_buff *skb, - unsigned int protoff, int invert, int *hotdrop) { @@ -39,7 +33,8 @@ mssoption_match(u_int16_t min, u_int16_t max, unsigned int i, optlen; /* If we don't have the whole header, drop packet. */ - th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); + th = skb_header_pointer(skb, skb->nh.iph->ihl * 4, + sizeof(_tcph), &_tcph); if (th == NULL) goto dropit; @@ -52,7 +47,8 @@ mssoption_match(u_int16_t min, u_int16_t max, goto out; /* Truncated options. */ - op = skb_header_pointer(skb, protoff + sizeof(*th), optlen, _opt); + op = skb_header_pointer(skb, skb->nh.iph->ihl * 4 + sizeof(*th), + optlen, _opt); if (op == NULL) goto dropit; @@ -83,24 +79,22 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { - const struct xt_tcpmss_match_info *info = matchinfo; + const struct ipt_tcpmss_match_info *info = matchinfo; - return mssoption_match(info->mss_min, info->mss_max, skb, protoff, + return mssoption_match(info->mss_min, info->mss_max, skb, info->invert, hotdrop); } static int checkentry(const char *tablename, - const void *ipinfo, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - const struct ipt_ip *ip = ipinfo; - if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info))) + if (matchsize != IPT_ALIGN(sizeof(struct ipt_tcpmss_match_info))) return 0; /* Must specify -p tcp */ @@ -112,60 +106,21 @@ checkentry(const char *tablename, return 1; } -static int -checkentry6(const char *tablename, - const void *ipinfo, - void *matchinfo, - unsigned int matchsize, - unsigned int hook_mask) -{ - const struct ip6t_ip6 *ip = ipinfo; - - if (matchsize != XT_ALIGN(sizeof(struct xt_tcpmss_match_info))) - return 0; - - /* Must specify -p tcp */ - if (ip->proto != IPPROTO_TCP || (ip->invflags & XT_INV_PROTO)) { - printk("tcpmss: Only works on TCP packets\n"); - return 0; - } - - return 1; -} - -static struct xt_match tcpmss_match = { +static struct ipt_match tcpmss_match = { .name = "tcpmss", .match = &match, .checkentry = &checkentry, .me = THIS_MODULE, }; -static struct xt_match tcpmss6_match = { - .name = "tcpmss", - .match = &match, - .checkentry = &checkentry6, - .me = THIS_MODULE, -}; - - static int __init init(void) { - int ret; - ret = xt_register_match(AF_INET, &tcpmss_match); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &tcpmss6_match); - if (ret) - xt_unregister_match(AF_INET, &tcpmss_match); - - return ret; + return ipt_register_match(&tcpmss_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET6, &tcpmss6_match); - xt_unregister_match(AF_INET, &tcpmss_match); + ipt_unregister_match(&tcpmss_match); } module_init(init); diff --git a/trunk/net/ipv4/netfilter/ipt_tos.c b/trunk/net/ipv4/netfilter/ipt_tos.c index 9ab765e126f2..086a1bb61e3e 100644 --- a/trunk/net/ipv4/netfilter/ipt_tos.c +++ b/trunk/net/ipv4/netfilter/ipt_tos.c @@ -23,7 +23,6 @@ match(const struct sk_buff *skb, const struct net_device *out, const void *matchinfo, int offset, - unsigned int protoff, int *hotdrop) { const struct ipt_tos_info *info = matchinfo; @@ -33,7 +32,7 @@ match(const struct sk_buff *skb, static int checkentry(const char *tablename, - const void *ip, + const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) diff --git a/trunk/net/ipv4/netfilter/ipt_ttl.c b/trunk/net/ipv4/netfilter/ipt_ttl.c index 82da53f430ab..219aa9de88cc 100644 --- a/trunk/net/ipv4/netfilter/ipt_ttl.c +++ b/trunk/net/ipv4/netfilter/ipt_ttl.c @@ -21,7 +21,7 @@ MODULE_LICENSE("GPL"); static int match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, - int offset, unsigned int protoff, int *hotdrop) + int offset, int *hotdrop) { const struct ipt_ttl_info *info = matchinfo; @@ -47,7 +47,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, return 0; } -static int checkentry(const char *tablename, const void *ip, +static int checkentry(const char *tablename, const struct ipt_ip *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { diff --git a/trunk/net/ipv4/netfilter/iptable_filter.c b/trunk/net/ipv4/netfilter/iptable_filter.c index 212a3079085b..260a4f0a2a90 100644 --- a/trunk/net/ipv4/netfilter/iptable_filter.c +++ b/trunk/net/ipv4/netfilter/iptable_filter.c @@ -78,8 +78,7 @@ static struct ipt_table packet_filter = { .name = "filter", .valid_hooks = FILTER_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, - .me = THIS_MODULE, - .af = AF_INET, + .me = THIS_MODULE }; /* The work comes in here from netfilter.c. */ diff --git a/trunk/net/ipv4/netfilter/iptable_mangle.c b/trunk/net/ipv4/netfilter/iptable_mangle.c index 3212a5cc4b6b..160eb11b6e2f 100644 --- a/trunk/net/ipv4/netfilter/iptable_mangle.c +++ b/trunk/net/ipv4/netfilter/iptable_mangle.c @@ -109,7 +109,6 @@ static struct ipt_table packet_mangler = { .valid_hooks = MANGLE_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, .me = THIS_MODULE, - .af = AF_INET, }; /* The work comes in here from netfilter.c. */ diff --git a/trunk/net/ipv4/netfilter/iptable_raw.c b/trunk/net/ipv4/netfilter/iptable_raw.c index fdb9e9c81e81..47449ba83eb9 100644 --- a/trunk/net/ipv4/netfilter/iptable_raw.c +++ b/trunk/net/ipv4/netfilter/iptable_raw.c @@ -83,8 +83,7 @@ static struct ipt_table packet_raw = { .name = "raw", .valid_hooks = RAW_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, - .me = THIS_MODULE, - .af = AF_INET, + .me = THIS_MODULE }; /* The work comes in here from netfilter.c. */ diff --git a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 167619f638c6..0c56c52a3831 100644 --- a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c @@ -575,7 +575,7 @@ MODULE_LICENSE("GPL"); static int __init init(void) { - need_conntrack(); + need_nf_conntrack(); return init_or_cleanup(1); } @@ -587,4 +587,9 @@ static void __exit fini(void) module_init(init); module_exit(fini); +void need_ip_conntrack(void) +{ +} + +EXPORT_SYMBOL(need_ip_conntrack); EXPORT_SYMBOL(nf_ct_ipv4_gather_frags); diff --git a/trunk/net/ipv4/xfrm4_state.c b/trunk/net/ipv4/xfrm4_state.c index dbabf81a9b7b..d23e07fc81fa 100644 --- a/trunk/net/ipv4/xfrm4_state.c +++ b/trunk/net/ipv4/xfrm4_state.c @@ -42,21 +42,6 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, x->props.saddr = tmpl->saddr; if (x->props.saddr.a4 == 0) x->props.saddr.a4 = saddr->a4; - if (tmpl->mode && x->props.saddr.a4 == 0) { - struct rtable *rt; - struct flowi fl_tunnel = { - .nl_u = { - .ip4_u = { - .daddr = x->id.daddr.a4, - } - } - }; - if (!xfrm_dst_lookup((struct xfrm_dst **)&rt, - &fl_tunnel, AF_INET)) { - x->props.saddr.a4 = rt->rt_src; - dst_release(&rt->u.dst); - } - } x->props.mode = tmpl->mode; x->props.reqid = tmpl->reqid; x->props.family = AF_INET; diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index dfb4f145a139..7129d4239755 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -2644,7 +2644,7 @@ static int if6_seq_show(struct seq_file *seq, void *v) { struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v; seq_printf(seq, - NIP6_FMT " %02x %02x %02x %02x %8s\n", + "%04x%04x%04x%04x%04x%04x%04x%04x %02x %02x %02x %02x %8s\n", NIP6(ifp->addr), ifp->idev->dev->ifindex, ifp->prefix_len, diff --git a/trunk/net/ipv6/ah6.c b/trunk/net/ipv6/ah6.c index c7932cb420a5..13cc7f895583 100644 --- a/trunk/net/ipv6/ah6.c +++ b/trunk/net/ipv6/ah6.c @@ -332,7 +332,8 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (!x) return; - NETDEBUG(KERN_DEBUG "pmtu discovery on SA AH/%08x/" NIP6_FMT "\n", + NETDEBUG(KERN_DEBUG "pmtu discovery on SA AH/%08x/" + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", ntohl(ah->spi), NIP6(iph->daddr)); xfrm_state_put(x); diff --git a/trunk/net/ipv6/anycast.c b/trunk/net/ipv6/anycast.c index 72bd08af2dfb..65e73ac0d6d0 100644 --- a/trunk/net/ipv6/anycast.c +++ b/trunk/net/ipv6/anycast.c @@ -532,7 +532,9 @@ static int ac6_seq_show(struct seq_file *seq, void *v) struct ac6_iter_state *state = ac6_seq_private(seq); seq_printf(seq, - "%-4d %-15s " NIP6_FMT " %5d\n", + "%-4d %-15s " + "%04x%04x%04x%04x%04x%04x%04x%04x " + "%5d\n", state->dev->ifindex, state->dev->name, NIP6(im->aca_addr), im->aca_users); diff --git a/trunk/net/ipv6/esp6.c b/trunk/net/ipv6/esp6.c index 7b5b94f13902..6de8ee1a5ad9 100644 --- a/trunk/net/ipv6/esp6.c +++ b/trunk/net/ipv6/esp6.c @@ -266,7 +266,8 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, esph->spi, IPPROTO_ESP, AF_INET6); if (!x) return; - printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/" NIP6_FMT "\n", + printk(KERN_DEBUG "pmtu discovery on SA ESP/%08x/" + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", ntohl(esph->spi), NIP6(iph->daddr)); xfrm_state_put(x); } diff --git a/trunk/net/ipv6/icmp.c b/trunk/net/ipv6/icmp.c index fcf883183cef..53c81fcd20ba 100644 --- a/trunk/net/ipv6/icmp.c +++ b/trunk/net/ipv6/icmp.c @@ -607,7 +607,7 @@ static int icmpv6_rcv(struct sk_buff **pskb) skb->csum = ~csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6, 0); if (__skb_checksum_complete(skb)) { - LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n", + LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n", NIP6(*saddr), NIP6(*daddr)); goto discard_it; } diff --git a/trunk/net/ipv6/ip6_flowlabel.c b/trunk/net/ipv6/ip6_flowlabel.c index 4183c8dac7f6..964ad9d1276d 100644 --- a/trunk/net/ipv6/ip6_flowlabel.c +++ b/trunk/net/ipv6/ip6_flowlabel.c @@ -629,7 +629,9 @@ static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) { while(fl) { seq_printf(seq, - "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_FMT " %-4d\n", + "%05X %-1d %-6d %-6d %-6ld %-8ld " + "%02x%02x%02x%02x%02x%02x%02x%02x " + "%-4d\n", (unsigned)ntohl(fl->label), fl->share, (unsigned)fl->owner, @@ -645,8 +647,8 @@ static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) static int ip6fl_seq_show(struct seq_file *seq, void *v) { if (v == SEQ_START_TOKEN) - seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-39s %s\n", - "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); + seq_puts(seq, "Label S Owner Users Linger Expires " + "Dst Opt\n"); else ip6fl_fl_seq_show(seq, v); return 0; diff --git a/trunk/net/ipv6/ipcomp6.c b/trunk/net/ipv6/ipcomp6.c index d511a884dad0..626dd39685f2 100644 --- a/trunk/net/ipv6/ipcomp6.c +++ b/trunk/net/ipv6/ipcomp6.c @@ -212,7 +212,8 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if (!x) return; - printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/" NIP6_FMT "\n", + printk(KERN_DEBUG "pmtu discovery on SA IPCOMP/%08x/" + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", spi, NIP6(iph->daddr)); xfrm_state_put(x); } diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index 0e03eabfb9da..cc3e9f560867 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -2373,7 +2373,7 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v) struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); seq_printf(seq, - "%-4d %-15s " NIP6_FMT " %5d %08X %ld\n", + "%-4d %-15s %04x%04x%04x%04x%04x%04x%04x%04x %5d %08X %ld\n", state->dev->ifindex, state->dev->name, NIP6(im->mca_addr), im->mca_users, im->mca_flags, @@ -2542,12 +2542,15 @@ static int igmp6_mcf_seq_show(struct seq_file *seq, void *v) if (v == SEQ_START_TOKEN) { seq_printf(seq, "%3s %6s " - "%39s %39s %6s %6s\n", "Idx", + "%32s %32s %6s %6s\n", "Idx", "Device", "Multicast Address", "Source Address", "INC", "EXC"); } else { seq_printf(seq, - "%3d %6.6s " NIP6_FMT " " NIP6_FMT " %6lu %6lu\n", + "%3d %6.6s " + "%04x%04x%04x%04x%04x%04x%04x%04x " + "%04x%04x%04x%04x%04x%04x%04x%04x " + "%6lu %6lu\n", state->dev->ifindex, state->dev->name, NIP6(state->im->mca_addr), NIP6(psf->sf_addr), diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index cb8856b1d951..305d9ee6d7db 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -692,7 +692,7 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb) if (!(neigh->nud_state & NUD_VALID)) { ND_PRINTK1(KERN_DEBUG "%s(): trying to ucast probe in NUD_INVALID: " - NIP6_FMT "\n", + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", __FUNCTION__, NIP6(*target)); } diff --git a/trunk/net/ipv6/netfilter/Kconfig b/trunk/net/ipv6/netfilter/Kconfig index 2d6f8ecbc27b..105dd69ee9fb 100644 --- a/trunk/net/ipv6/netfilter/Kconfig +++ b/trunk/net/ipv6/netfilter/Kconfig @@ -41,7 +41,6 @@ config IP6_NF_QUEUE config IP6_NF_IPTABLES tristate "IP6 tables support (required for filtering/masq/NAT)" - depends on NETFILTER_XTABLES help ip6tables is a general, extensible packet identification framework. Currently only the packet filtering and packet mangling subsystem @@ -51,6 +50,25 @@ config IP6_NF_IPTABLES To compile it as a module, choose M here. If unsure, say N. # The simple matches. +config IP6_NF_MATCH_LIMIT + tristate "limit match support" + depends on IP6_NF_IPTABLES + help + limit matching allows you to control the rate at which a rule can be + matched: mainly useful in combination with the LOG target ("LOG + target support", below) and to avoid some Denial of Service attacks. + + To compile it as a module, choose M here. If unsure, say N. + +config IP6_NF_MATCH_MAC + tristate "MAC address match support" + depends on IP6_NF_IPTABLES + help + mac matching allows you to match packets based on the source + Ethernet address of the packet. + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_MATCH_RT tristate "Routing header match support" depends on IP6_NF_IPTABLES @@ -106,6 +124,16 @@ config IP6_NF_MATCH_OWNER To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_MATCH_MARK + tristate "netfilter MARK match support" + depends on IP6_NF_IPTABLES + help + Netfilter mark matching allows you to match packets based on the + `nfmark' value in the packet. This can be set by the MARK target + (see below). + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_MATCH_IPV6HEADER tristate "IPv6 Extension Headers Match" depends on IP6_NF_IPTABLES @@ -123,6 +151,15 @@ config IP6_NF_MATCH_AHESP To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_MATCH_LENGTH + tristate "Packet Length match support" + depends on IP6_NF_IPTABLES + help + This option allows you to match the length of a packet against a + specific value or range of values. + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_MATCH_EUI64 tristate "EUI64 address check" depends on IP6_NF_IPTABLES @@ -133,6 +170,15 @@ config IP6_NF_MATCH_EUI64 To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_MATCH_PHYSDEV + tristate "Physdev match support" + depends on IP6_NF_IPTABLES && BRIDGE_NETFILTER + help + Physdev packet matching matches against the physical bridge ports + the IP packet arrived on or will leave by. + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_MATCH_POLICY tristate "IPsec policy match support" depends on IP6_NF_IPTABLES && XFRM @@ -173,6 +219,17 @@ config IP6_NF_TARGET_REJECT To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_TARGET_NFQUEUE + tristate "NFQUEUE Target Support" + depends on IP6_NF_IPTABLES + help + This Target replaced the old obsolete QUEUE target. + + As opposed to QUEUE, it supports 65535 different queues, + not just one. + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_MANGLE tristate "Packet mangling" depends on IP6_NF_IPTABLES @@ -183,6 +240,19 @@ config IP6_NF_MANGLE To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_TARGET_MARK + tristate "MARK target support" + depends on IP6_NF_MANGLE + help + This option adds a `MARK' target, which allows you to create rules + in the `mangle' table which alter the netfilter mark (nfmark) field + associated with the packet packet prior to routing. This can change + the routing method (see `Use netfilter MARK value as routing + key') and can also be used by other subsystems to change their + behavior. + + To compile it as a module, choose M here. If unsure, say N. + config IP6_NF_TARGET_HL tristate 'HL (hoplimit) target support' depends on IP6_NF_MANGLE diff --git a/trunk/net/ipv6/netfilter/Makefile b/trunk/net/ipv6/netfilter/Makefile index 663b4749820d..c0c809b426e8 100644 --- a/trunk/net/ipv6/netfilter/Makefile +++ b/trunk/net/ipv6/netfilter/Makefile @@ -4,7 +4,10 @@ # Link order matters here. obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o +obj-$(CONFIG_IP6_NF_MATCH_LIMIT) += ip6t_limit.o +obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o obj-$(CONFIG_IP6_NF_MATCH_LENGTH) += ip6t_length.o +obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o @@ -14,9 +17,12 @@ obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o +obj-$(CONFIG_IP6_NF_MATCH_PHYSDEV) += ip6t_physdev.o obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o +obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o obj-$(CONFIG_IP6_NF_TARGET_HL) += ip6t_HL.o +obj-$(CONFIG_IP6_NF_TARGET_NFQUEUE) += ip6t_NFQUEUE.o obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o diff --git a/trunk/net/ipv6/netfilter/ip6_tables.c b/trunk/net/ipv6/netfilter/ip6_tables.c index 847068fd3367..1390370186d9 100644 --- a/trunk/net/ipv6/netfilter/ip6_tables.c +++ b/trunk/net/ipv6/netfilter/ip6_tables.c @@ -13,9 +13,6 @@ * a table * 06 Jun 2002 Andras Kis-Szabo * - new extension header parser code - * 15 Oct 2005 Harald Welte - * - Unification of {ip,ip6}_tables into x_tables - * - Removed tcp and udp code, since it's not ipv6 specific */ #include @@ -26,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -34,7 +33,6 @@ #include #include -#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Netfilter Core Team "); @@ -69,8 +67,13 @@ do { \ #else #define IP_NF_ASSERT(x) #endif +#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) +static DECLARE_MUTEX(ip6t_mutex); +/* Must have mutex */ +#define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) +#define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0) #include #if 0 @@ -88,6 +91,30 @@ do { \ Hence the start of any table is given by get_table() below. */ +/* The table itself */ +struct ip6t_table_info +{ + /* Size per table */ + unsigned int size; + /* Number of entries: FIXME. --RR */ + unsigned int number; + /* Initial number of entries. Needed for module usage count */ + unsigned int initial_entries; + + /* Entry points and underflows */ + unsigned int hook_entry[NF_IP6_NUMHOOKS]; + unsigned int underflow[NF_IP6_NUMHOOKS]; + + /* ip6t_entry tables: one per CPU */ + void *entries[NR_CPUS]; +}; + +static LIST_HEAD(ip6t_target); +static LIST_HEAD(ip6t_match); +static LIST_HEAD(ip6t_tables); +#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0) +#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0) + #if 0 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) @@ -270,7 +297,7 @@ ip6t_do_table(struct sk_buff **pskb, unsigned int hook, const struct net_device *in, const struct net_device *out, - struct xt_table *table, + struct ip6t_table *table, void *userdata) { static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); @@ -282,7 +309,6 @@ ip6t_do_table(struct sk_buff **pskb, const char *indev, *outdev; void *table_base; struct ip6t_entry *e, *back; - struct xt_table_info *private; /* Initialization */ indev = in ? in->name : nulldevname; @@ -295,10 +321,9 @@ ip6t_do_table(struct sk_buff **pskb, * match it. */ read_lock_bh(&table->lock); - private = table->private; IP_NF_ASSERT(table->valid_hooks & (1 << hook)); - table_base = (void *)private->entries[smp_processor_id()]; - e = get_entry(table_base, private->hook_entry[hook]); + table_base = (void *)table->private->entries[smp_processor_id()]; + e = get_entry(table_base, table->private->hook_entry[hook]); #ifdef CONFIG_NETFILTER_DEBUG /* Check noone else using our table */ @@ -314,7 +339,7 @@ ip6t_do_table(struct sk_buff **pskb, #endif /* For return from builtin chain */ - back = get_entry(table_base, private->underflow[hook]); + back = get_entry(table_base, table->private->underflow[hook]); do { IP_NF_ASSERT(e); @@ -414,6 +439,145 @@ ip6t_do_table(struct sk_buff **pskb, #endif } +/* + * These are weird, but module loading must not be done with mutex + * held (since they will register), and we have to have a single + * function to use try_then_request_module(). + */ + +/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ +static inline struct ip6t_table *find_table_lock(const char *name) +{ + struct ip6t_table *t; + + if (down_interruptible(&ip6t_mutex) != 0) + return ERR_PTR(-EINTR); + + list_for_each_entry(t, &ip6t_tables, list) + if (strcmp(t->name, name) == 0 && try_module_get(t->me)) + return t; + up(&ip6t_mutex); + return NULL; +} + +/* Find match, grabs ref. Returns ERR_PTR() on error. */ +static inline struct ip6t_match *find_match(const char *name, u8 revision) +{ + struct ip6t_match *m; + int err = 0; + + if (down_interruptible(&ip6t_mutex) != 0) + return ERR_PTR(-EINTR); + + list_for_each_entry(m, &ip6t_match, list) { + if (strcmp(m->name, name) == 0) { + if (m->revision == revision) { + if (try_module_get(m->me)) { + up(&ip6t_mutex); + return m; + } + } else + err = -EPROTOTYPE; /* Found something. */ + } + } + up(&ip6t_mutex); + return ERR_PTR(err); +} + +/* Find target, grabs ref. Returns ERR_PTR() on error. */ +static inline struct ip6t_target *find_target(const char *name, u8 revision) +{ + struct ip6t_target *t; + int err = 0; + + if (down_interruptible(&ip6t_mutex) != 0) + return ERR_PTR(-EINTR); + + list_for_each_entry(t, &ip6t_target, list) { + if (strcmp(t->name, name) == 0) { + if (t->revision == revision) { + if (try_module_get(t->me)) { + up(&ip6t_mutex); + return t; + } + } else + err = -EPROTOTYPE; /* Found something. */ + } + } + up(&ip6t_mutex); + return ERR_PTR(err); +} + +struct ip6t_target *ip6t_find_target(const char *name, u8 revision) +{ + struct ip6t_target *target; + + target = try_then_request_module(find_target(name, revision), + "ip6t_%s", name); + if (IS_ERR(target) || !target) + return NULL; + return target; +} + +static int match_revfn(const char *name, u8 revision, int *bestp) +{ + struct ip6t_match *m; + int have_rev = 0; + + list_for_each_entry(m, &ip6t_match, list) { + if (strcmp(m->name, name) == 0) { + if (m->revision > *bestp) + *bestp = m->revision; + if (m->revision == revision) + have_rev = 1; + } + } + return have_rev; +} + +static int target_revfn(const char *name, u8 revision, int *bestp) +{ + struct ip6t_target *t; + int have_rev = 0; + + list_for_each_entry(t, &ip6t_target, list) { + if (strcmp(t->name, name) == 0) { + if (t->revision > *bestp) + *bestp = t->revision; + if (t->revision == revision) + have_rev = 1; + } + } + return have_rev; +} + +/* Returns true or fals (if no such extension at all) */ +static inline int find_revision(const char *name, u8 revision, + int (*revfn)(const char *, u8, int *), + int *err) +{ + int have_rev, best = -1; + + if (down_interruptible(&ip6t_mutex) != 0) { + *err = -EINTR; + return 1; + } + have_rev = revfn(name, revision, &best); + up(&ip6t_mutex); + + /* Nothing at all? Return 0 to try loading module. */ + if (best == -1) { + *err = -ENOENT; + return 0; + } + + *err = best; + if (!have_rev) + *err = -EPROTONOSUPPORT; + return 1; +} + + /* All zeroes == unconditional rule. */ static inline int unconditional(const struct ip6t_ip6 *ipv6) @@ -430,7 +594,7 @@ unconditional(const struct ip6t_ip6 *ipv6) /* Figures out from what hook each rule can be called: returns 0 if there are loops. Puts hook bitmask in comefrom. */ static int -mark_source_chains(struct xt_table_info *newinfo, +mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks, void *entry0) { unsigned int hook; @@ -576,11 +740,11 @@ check_match(struct ip6t_entry_match *m, { struct ip6t_match *match; - match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name, - m->u.user.revision), + match = try_then_request_module(find_match(m->u.user.name, + m->u.user.revision), "ip6t_%s", m->u.user.name); if (IS_ERR(match) || !match) { - duprintf("check_match: `%s' not found\n", m->u.user.name); + duprintf("check_match: `%s' not found\n", m->u.user.name); return match ? PTR_ERR(match) : -ENOENT; } m->u.kernel.match = match; @@ -621,9 +785,8 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, goto cleanup_matches; t = ip6t_get_target(e); - target = try_then_request_module(xt_find_target(AF_INET6, - t->u.user.name, - t->u.user.revision), + target = try_then_request_module(find_target(t->u.user.name, + t->u.user.revision), "ip6t_%s", t->u.user.name); if (IS_ERR(target) || !target) { duprintf("check_entry: `%s' not found\n", t->u.user.name); @@ -659,7 +822,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, static inline int check_entry_size_and_hooks(struct ip6t_entry *e, - struct xt_table_info *newinfo, + struct ip6t_table_info *newinfo, unsigned char *base, unsigned char *limit, const unsigned int *hook_entries, @@ -693,7 +856,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, < 0 (not IP6T_RETURN). --RR */ /* Clear counters and comefrom */ - e->counters = ((struct xt_counters) { 0, 0 }); + e->counters = ((struct ip6t_counters) { 0, 0 }); e->comefrom = 0; (*i)++; @@ -723,7 +886,7 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i) static int translate_table(const char *name, unsigned int valid_hooks, - struct xt_table_info *newinfo, + struct ip6t_table_info *newinfo, void *entry0, unsigned int size, unsigned int number, @@ -800,10 +963,48 @@ translate_table(const char *name, return ret; } +static struct ip6t_table_info * +replace_table(struct ip6t_table *table, + unsigned int num_counters, + struct ip6t_table_info *newinfo, + int *error) +{ + struct ip6t_table_info *oldinfo; + +#ifdef CONFIG_NETFILTER_DEBUG + { + int cpu; + + for_each_cpu(cpu) { + struct ip6t_entry *table_base = newinfo->entries[cpu]; + if (table_base) + table_base->comefrom = 0xdead57ac; + } + } +#endif + + /* Do the substitution. */ + write_lock_bh(&table->lock); + /* Check inside lock: is the old number correct? */ + if (num_counters != table->private->number) { + duprintf("num_counters != table->private->number (%u/%u)\n", + num_counters, table->private->number); + write_unlock_bh(&table->lock); + *error = -EAGAIN; + return NULL; + } + oldinfo = table->private; + table->private = newinfo; + newinfo->initial_entries = oldinfo->initial_entries; + write_unlock_bh(&table->lock); + + return oldinfo; +} + /* Gets counters. */ static inline int add_entry_to_counter(const struct ip6t_entry *e, - struct xt_counters total[], + struct ip6t_counters total[], unsigned int *i) { ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); @@ -824,8 +1025,8 @@ set_entry_to_counter(const struct ip6t_entry *e, } static void -get_counters(const struct xt_table_info *t, - struct xt_counters counters[]) +get_counters(const struct ip6t_table_info *t, + struct ip6t_counters counters[]) { unsigned int cpu; unsigned int i; @@ -859,20 +1060,19 @@ get_counters(const struct xt_table_info *t, static int copy_entries_to_user(unsigned int total_size, - struct xt_table *table, + struct ip6t_table *table, void __user *userptr) { unsigned int off, num, countersize; struct ip6t_entry *e; - struct xt_counters *counters; - struct xt_table_info *private = table->private; + struct ip6t_counters *counters; int ret = 0; void *loc_cpu_entry; /* We need atomic snapshot of counters: rest doesn't change (other than comefrom, which userspace doesn't care about). */ - countersize = sizeof(struct xt_counters) * private->number; + countersize = sizeof(struct ip6t_counters) * table->private->number; counters = vmalloc(countersize); if (counters == NULL) @@ -880,11 +1080,11 @@ copy_entries_to_user(unsigned int total_size, /* First, sum counters... */ write_lock_bh(&table->lock); - get_counters(private, counters); + get_counters(table->private, counters); write_unlock_bh(&table->lock); /* choose the copy that is on ourc node/cpu */ - loc_cpu_entry = private->entries[raw_smp_processor_id()]; + loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) { ret = -EFAULT; goto free_counters; @@ -943,42 +1143,87 @@ get_entries(const struct ip6t_get_entries *entries, struct ip6t_get_entries __user *uptr) { int ret; - struct xt_table *t; + struct ip6t_table *t; - t = xt_find_table_lock(AF_INET6, entries->name); + t = find_table_lock(entries->name); if (t && !IS_ERR(t)) { - struct xt_table_info *private = t->private; - duprintf("t->private->number = %u\n", private->number); - if (entries->size == private->size) - ret = copy_entries_to_user(private->size, + duprintf("t->private->number = %u\n", + t->private->number); + if (entries->size == t->private->size) + ret = copy_entries_to_user(t->private->size, t, uptr->entrytable); else { duprintf("get_entries: I've got %u not %u!\n", - private->size, entries->size); + t->private->size, + entries->size); ret = -EINVAL; } module_put(t->me); - xt_table_unlock(t); + up(&ip6t_mutex); } else ret = t ? PTR_ERR(t) : -ENOENT; return ret; } +static void free_table_info(struct ip6t_table_info *info) +{ + int cpu; + for_each_cpu(cpu) { + if (info->size <= PAGE_SIZE) + kfree(info->entries[cpu]); + else + vfree(info->entries[cpu]); + } + kfree(info); +} + +static struct ip6t_table_info *alloc_table_info(unsigned int size) +{ + struct ip6t_table_info *newinfo; + int cpu; + + newinfo = kzalloc(sizeof(struct ip6t_table_info), GFP_KERNEL); + if (!newinfo) + return NULL; + + newinfo->size = size; + + for_each_cpu(cpu) { + if (size <= PAGE_SIZE) + newinfo->entries[cpu] = kmalloc_node(size, + GFP_KERNEL, + cpu_to_node(cpu)); + else + newinfo->entries[cpu] = vmalloc_node(size, + cpu_to_node(cpu)); + if (newinfo->entries[cpu] == NULL) { + free_table_info(newinfo); + return NULL; + } + } + + return newinfo; +} + static int do_replace(void __user *user, unsigned int len) { int ret; struct ip6t_replace tmp; - struct xt_table *t; - struct xt_table_info *newinfo, *oldinfo; - struct xt_counters *counters; + struct ip6t_table *t; + struct ip6t_table_info *newinfo, *oldinfo; + struct ip6t_counters *counters; void *loc_cpu_entry, *loc_cpu_old_entry; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) return -EFAULT; - newinfo = xt_alloc_table_info(tmp.size); + /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ + if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages) + return -ENOMEM; + + newinfo = alloc_table_info(tmp.size); if (!newinfo) return -ENOMEM; @@ -990,7 +1235,7 @@ do_replace(void __user *user, unsigned int len) goto free_newinfo; } - counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); + counters = vmalloc(tmp.num_counters * sizeof(struct ip6t_counters)); if (!counters) { ret = -ENOMEM; goto free_newinfo; @@ -1004,7 +1249,7 @@ do_replace(void __user *user, unsigned int len) duprintf("ip_tables: Translated table\n"); - t = try_then_request_module(xt_find_table_lock(AF_INET6, tmp.name), + t = try_then_request_module(find_table_lock(tmp.name), "ip6table_%s", tmp.name); if (!t || IS_ERR(t)) { ret = t ? PTR_ERR(t) : -ENOENT; @@ -1019,7 +1264,7 @@ do_replace(void __user *user, unsigned int len) goto put_module; } - oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); + oldinfo = replace_table(t, tmp.num_counters, newinfo, &ret); if (!oldinfo) goto put_module; @@ -1038,23 +1283,23 @@ do_replace(void __user *user, unsigned int len) /* Decrease module usage counts and free resource */ loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); - xt_free_table_info(oldinfo); + free_table_info(oldinfo); if (copy_to_user(tmp.counters, counters, - sizeof(struct xt_counters) * tmp.num_counters) != 0) + sizeof(struct ip6t_counters) * tmp.num_counters) != 0) ret = -EFAULT; vfree(counters); - xt_table_unlock(t); + up(&ip6t_mutex); return ret; put_module: module_put(t->me); - xt_table_unlock(t); + up(&ip6t_mutex); free_newinfo_counters_untrans: IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); free_newinfo_counters: vfree(counters); free_newinfo: - xt_free_table_info(newinfo); + free_table_info(newinfo); return ret; } @@ -1062,7 +1307,7 @@ do_replace(void __user *user, unsigned int len) * and everything is OK. */ static inline int add_counter_to_entry(struct ip6t_entry *e, - const struct xt_counters addme[], + const struct ip6t_counters addme[], unsigned int *i) { #if 0 @@ -1084,16 +1329,15 @@ static int do_add_counters(void __user *user, unsigned int len) { unsigned int i; - struct xt_counters_info tmp, *paddc; - struct xt_table_info *private; - struct xt_table *t; + struct ip6t_counters_info tmp, *paddc; + struct ip6t_table *t; int ret = 0; void *loc_cpu_entry; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) return -EFAULT; - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) + if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ip6t_counters)) return -EINVAL; paddc = vmalloc(len); @@ -1105,30 +1349,29 @@ do_add_counters(void __user *user, unsigned int len) goto free; } - t = xt_find_table_lock(AF_INET6, tmp.name); + t = find_table_lock(tmp.name); if (!t || IS_ERR(t)) { ret = t ? PTR_ERR(t) : -ENOENT; goto free; } write_lock_bh(&t->lock); - private = t->private; - if (private->number != paddc->num_counters) { + if (t->private->number != paddc->num_counters) { ret = -EINVAL; goto unlock_up_free; } i = 0; /* Choose the copy that is on our node */ - loc_cpu_entry = private->entries[smp_processor_id()]; + loc_cpu_entry = t->private->entries[smp_processor_id()]; IP6T_ENTRY_ITERATE(loc_cpu_entry, - private->size, + t->private->size, add_counter_to_entry, paddc->counters, &i); unlock_up_free: write_unlock_bh(&t->lock); - xt_table_unlock(t); + up(&ip6t_mutex); module_put(t->me); free: vfree(paddc); @@ -1172,7 +1415,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) switch (cmd) { case IP6T_SO_GET_INFO: { char name[IP6T_TABLE_MAXNAMELEN]; - struct xt_table *t; + struct ip6t_table *t; if (*len != sizeof(struct ip6t_getinfo)) { duprintf("length %u != %u\n", *len, @@ -1187,26 +1430,25 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) } name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; - t = try_then_request_module(xt_find_table_lock(AF_INET6, name), + t = try_then_request_module(find_table_lock(name), "ip6table_%s", name); if (t && !IS_ERR(t)) { struct ip6t_getinfo info; - struct xt_table_info *private = t->private; info.valid_hooks = t->valid_hooks; - memcpy(info.hook_entry, private->hook_entry, + memcpy(info.hook_entry, t->private->hook_entry, sizeof(info.hook_entry)); - memcpy(info.underflow, private->underflow, + memcpy(info.underflow, t->private->underflow, sizeof(info.underflow)); - info.num_entries = private->number; - info.size = private->size; + info.num_entries = t->private->number; + info.size = t->private->size; memcpy(info.name, name, sizeof(info.name)); if (copy_to_user(user, &info, *len) != 0) ret = -EFAULT; else ret = 0; - xt_table_unlock(t); + up(&ip6t_mutex); module_put(t->me); } else ret = t ? PTR_ERR(t) : -ENOENT; @@ -1233,7 +1475,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) case IP6T_SO_GET_REVISION_MATCH: case IP6T_SO_GET_REVISION_TARGET: { struct ip6t_get_revision rev; - int target; + int (*revfn)(const char *, u8, int *); if (*len != sizeof(rev)) { ret = -EINVAL; @@ -1245,13 +1487,12 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) } if (cmd == IP6T_SO_GET_REVISION_TARGET) - target = 1; + revfn = target_revfn; else - target = 0; + revfn = match_revfn; - try_then_request_module(xt_find_revision(AF_INET6, rev.name, - rev.revision, - target, &ret), + try_then_request_module(find_revision(rev.name, rev.revision, + revfn, &ret), "ip6t_%s", rev.name); break; } @@ -1264,16 +1505,61 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) return ret; } -int ip6t_register_table(struct xt_table *table, +/* Registration hooks for targets. */ +int +ip6t_register_target(struct ip6t_target *target) +{ + int ret; + + ret = down_interruptible(&ip6t_mutex); + if (ret != 0) + return ret; + list_add(&target->list, &ip6t_target); + up(&ip6t_mutex); + return ret; +} + +void +ip6t_unregister_target(struct ip6t_target *target) +{ + down(&ip6t_mutex); + LIST_DELETE(&ip6t_target, target); + up(&ip6t_mutex); +} + +int +ip6t_register_match(struct ip6t_match *match) +{ + int ret; + + ret = down_interruptible(&ip6t_mutex); + if (ret != 0) + return ret; + + list_add(&match->list, &ip6t_match); + up(&ip6t_mutex); + + return ret; +} + +void +ip6t_unregister_match(struct ip6t_match *match) +{ + down(&ip6t_mutex); + LIST_DELETE(&ip6t_match, match); + up(&ip6t_mutex); +} + +int ip6t_register_table(struct ip6t_table *table, const struct ip6t_replace *repl) { int ret; - struct xt_table_info *newinfo; - static struct xt_table_info bootstrap + struct ip6t_table_info *newinfo; + static struct ip6t_table_info bootstrap = { 0, 0, 0, { 0 }, { 0 }, { } }; void *loc_cpu_entry; - newinfo = xt_alloc_table_info(repl->size); + newinfo = alloc_table_info(repl->size); if (!newinfo) return -ENOMEM; @@ -1287,29 +1573,244 @@ int ip6t_register_table(struct xt_table *table, repl->hook_entry, repl->underflow); if (ret != 0) { - xt_free_table_info(newinfo); + free_table_info(newinfo); return ret; } - if (xt_register_table(table, &bootstrap, newinfo) != 0) { - xt_free_table_info(newinfo); + ret = down_interruptible(&ip6t_mutex); + if (ret != 0) { + free_table_info(newinfo); return ret; } - return 0; + /* Don't autoload: we'd eat our tail... */ + if (list_named_find(&ip6t_tables, table->name)) { + ret = -EEXIST; + goto free_unlock; + } + + /* Simplifies replace_table code. */ + table->private = &bootstrap; + if (!replace_table(table, 0, newinfo, &ret)) + goto free_unlock; + + duprintf("table->private->number = %u\n", + table->private->number); + + /* save number of initial entries */ + table->private->initial_entries = table->private->number; + + rwlock_init(&table->lock); + list_prepend(&ip6t_tables, table); + + unlock: + up(&ip6t_mutex); + return ret; + + free_unlock: + free_table_info(newinfo); + goto unlock; } -void ip6t_unregister_table(struct xt_table *table) +void ip6t_unregister_table(struct ip6t_table *table) { - struct xt_table_info *private; void *loc_cpu_entry; - private = xt_unregister_table(table); + down(&ip6t_mutex); + LIST_DELETE(&ip6t_tables, table); + up(&ip6t_mutex); /* Decrease module usage counts and free resources */ - loc_cpu_entry = private->entries[raw_smp_processor_id()]; - IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); - xt_free_table_info(private); + loc_cpu_entry = table->private->entries[raw_smp_processor_id()]; + IP6T_ENTRY_ITERATE(loc_cpu_entry, table->private->size, + cleanup_entry, NULL); + free_table_info(table->private); +} + +/* Returns 1 if the port is matched by the range, 0 otherwise */ +static inline int +port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) +{ + int ret; + + ret = (port >= min && port <= max) ^ invert; + return ret; +} + +static int +tcp_find_option(u_int8_t option, + const struct sk_buff *skb, + unsigned int tcpoff, + unsigned int optlen, + int invert, + int *hotdrop) +{ + /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ + u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; + unsigned int i; + + duprintf("tcp_match: finding option\n"); + if (!optlen) + return invert; + /* If we don't have the whole header, drop packet. */ + op = skb_header_pointer(skb, tcpoff + sizeof(struct tcphdr), optlen, + _opt); + if (op == NULL) { + *hotdrop = 1; + return 0; + } + + for (i = 0; i < optlen; ) { + if (op[i] == option) return !invert; + if (op[i] < 2) i++; + else i += op[i+1]?:1; + } + + return invert; +} + +static int +tcp_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + struct tcphdr _tcph, *th; + const struct ip6t_tcp *tcpinfo = matchinfo; + + if (offset) { + /* To quote Alan: + + Don't allow a fragment of TCP 8 bytes in. Nobody normal + causes this. Its a cracker trying to break in by doing a + flag overwrite to pass the direction checks. + */ + if (offset == 1) { + duprintf("Dropping evil TCP offset=1 frag.\n"); + *hotdrop = 1; + } + /* Must not be a fragment. */ + return 0; + } + +#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) + + th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); + if (th == NULL) { + /* We've been asked to examine this packet, and we + can't. Hence, no choice but to drop. */ + duprintf("Dropping evil TCP offset=0 tinygram.\n"); + *hotdrop = 1; + return 0; + } + + if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], + ntohs(th->source), + !!(tcpinfo->invflags & IP6T_TCP_INV_SRCPT))) + return 0; + if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], + ntohs(th->dest), + !!(tcpinfo->invflags & IP6T_TCP_INV_DSTPT))) + return 0; + if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) + == tcpinfo->flg_cmp, + IP6T_TCP_INV_FLAGS)) + return 0; + if (tcpinfo->option) { + if (th->doff * 4 < sizeof(_tcph)) { + *hotdrop = 1; + return 0; + } + if (!tcp_find_option(tcpinfo->option, skb, protoff, + th->doff*4 - sizeof(*th), + tcpinfo->invflags & IP6T_TCP_INV_OPTION, + hotdrop)) + return 0; + } + return 1; +} + +/* Called when user tries to insert an entry of this type. */ +static int +tcp_checkentry(const char *tablename, + const struct ip6t_ip6 *ipv6, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + const struct ip6t_tcp *tcpinfo = matchinfo; + + /* Must specify proto == TCP, and no unknown invflags */ + return ipv6->proto == IPPROTO_TCP + && !(ipv6->invflags & IP6T_INV_PROTO) + && matchsize == IP6T_ALIGN(sizeof(struct ip6t_tcp)) + && !(tcpinfo->invflags & ~IP6T_TCP_INV_MASK); +} + +static int +udp_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + struct udphdr _udph, *uh; + const struct ip6t_udp *udpinfo = matchinfo; + + /* Must not be a fragment. */ + if (offset) + return 0; + + uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); + if (uh == NULL) { + /* We've been asked to examine this packet, and we + can't. Hence, no choice but to drop. */ + duprintf("Dropping evil UDP tinygram.\n"); + *hotdrop = 1; + return 0; + } + + return port_match(udpinfo->spts[0], udpinfo->spts[1], + ntohs(uh->source), + !!(udpinfo->invflags & IP6T_UDP_INV_SRCPT)) + && port_match(udpinfo->dpts[0], udpinfo->dpts[1], + ntohs(uh->dest), + !!(udpinfo->invflags & IP6T_UDP_INV_DSTPT)); +} + +/* Called when user tries to insert an entry of this type. */ +static int +udp_checkentry(const char *tablename, + const struct ip6t_ip6 *ipv6, + void *matchinfo, + unsigned int matchinfosize, + unsigned int hook_mask) +{ + const struct ip6t_udp *udpinfo = matchinfo; + + /* Must specify proto == UDP, and no unknown invflags */ + if (ipv6->proto != IPPROTO_UDP || (ipv6->invflags & IP6T_INV_PROTO)) { + duprintf("ip6t_udp: Protocol %u != %u\n", ipv6->proto, + IPPROTO_UDP); + return 0; + } + if (matchinfosize != IP6T_ALIGN(sizeof(struct ip6t_udp))) { + duprintf("ip6t_udp: matchsize %u != %u\n", + matchinfosize, IP6T_ALIGN(sizeof(struct ip6t_udp))); + return 0; + } + if (udpinfo->invflags & ~IP6T_UDP_INV_MASK) { + duprintf("ip6t_udp: unknown flags %X\n", + udpinfo->invflags); + return 0; + } + + return 1; } /* Returns 1 if the type and code is matched by the range, 0 otherwise */ @@ -1357,12 +1858,11 @@ icmp6_match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int icmp6_checkentry(const char *tablename, - const void *entry, + const struct ip6t_ip6 *ipv6, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - const struct ip6t_ip6 *ipv6 = entry; const struct ip6t_icmp *icmpinfo = matchinfo; /* Must specify proto == ICMP, and no unknown invflags */ @@ -1392,42 +1892,164 @@ static struct nf_sockopt_ops ip6t_sockopts = { .get = do_ip6t_get_ctl, }; +static struct ip6t_match tcp_matchstruct = { + .name = "tcp", + .match = &tcp_match, + .checkentry = &tcp_checkentry, +}; + +static struct ip6t_match udp_matchstruct = { + .name = "udp", + .match = &udp_match, + .checkentry = &udp_checkentry, +}; + static struct ip6t_match icmp6_matchstruct = { .name = "icmp6", .match = &icmp6_match, .checkentry = &icmp6_checkentry, }; +#ifdef CONFIG_PROC_FS +static inline int print_name(const char *i, + off_t start_offset, char *buffer, int length, + off_t *pos, unsigned int *count) +{ + if ((*count)++ >= start_offset) { + unsigned int namelen; + + namelen = sprintf(buffer + *pos, "%s\n", + i + sizeof(struct list_head)); + if (*pos + namelen > length) { + /* Stop iterating */ + return 1; + } + *pos += namelen; + } + return 0; +} + +static inline int print_target(const struct ip6t_target *t, + off_t start_offset, char *buffer, int length, + off_t *pos, unsigned int *count) +{ + if (t == &ip6t_standard_target || t == &ip6t_error_target) + return 0; + return print_name((char *)t, start_offset, buffer, length, pos, count); +} + +static int ip6t_get_tables(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ip6t_mutex) != 0) + return 0; + + LIST_FIND(&ip6t_tables, print_name, char *, + offset, buffer, length, &pos, &count); + + up(&ip6t_mutex); + + /* `start' hack - see fs/proc/generic.c line ~105 */ + *start=(char *)((unsigned long)count-offset); + return pos; +} + +static int ip6t_get_targets(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ip6t_mutex) != 0) + return 0; + + LIST_FIND(&ip6t_target, print_target, struct ip6t_target *, + offset, buffer, length, &pos, &count); + + up(&ip6t_mutex); + + *start = (char *)((unsigned long)count - offset); + return pos; +} + +static int ip6t_get_matches(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ip6t_mutex) != 0) + return 0; + + LIST_FIND(&ip6t_match, print_name, char *, + offset, buffer, length, &pos, &count); + + up(&ip6t_mutex); + + *start = (char *)((unsigned long)count - offset); + return pos; +} + +static const struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] = +{ { "ip6_tables_names", ip6t_get_tables }, + { "ip6_tables_targets", ip6t_get_targets }, + { "ip6_tables_matches", ip6t_get_matches }, + { NULL, NULL} }; +#endif /*CONFIG_PROC_FS*/ + static int __init init(void) { int ret; - xt_proto_init(AF_INET6); - /* Noone else will be downing sem now, so we won't sleep */ - xt_register_target(AF_INET6, &ip6t_standard_target); - xt_register_target(AF_INET6, &ip6t_error_target); - xt_register_match(AF_INET6, &icmp6_matchstruct); + down(&ip6t_mutex); + list_append(&ip6t_target, &ip6t_standard_target); + list_append(&ip6t_target, &ip6t_error_target); + list_append(&ip6t_match, &tcp_matchstruct); + list_append(&ip6t_match, &udp_matchstruct); + list_append(&ip6t_match, &icmp6_matchstruct); + up(&ip6t_mutex); /* Register setsockopt */ ret = nf_register_sockopt(&ip6t_sockopts); if (ret < 0) { duprintf("Unable to register sockopts.\n"); - xt_proto_fini(AF_INET6); return ret; } - printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); +#ifdef CONFIG_PROC_FS + { + struct proc_dir_entry *proc; + int i; + + for (i = 0; ip6t_proc_entry[i].name; i++) { + proc = proc_net_create(ip6t_proc_entry[i].name, 0, + ip6t_proc_entry[i].get_info); + if (!proc) { + while (--i >= 0) + proc_net_remove(ip6t_proc_entry[i].name); + nf_unregister_sockopt(&ip6t_sockopts); + return -ENOMEM; + } + proc->owner = THIS_MODULE; + } + } +#endif + + printk("ip6_tables: (C) 2000-2002 Netfilter core team\n"); return 0; } static void __exit fini(void) { nf_unregister_sockopt(&ip6t_sockopts); - xt_unregister_match(AF_INET6, &icmp6_matchstruct); - xt_unregister_target(AF_INET6, &ip6t_error_target); - xt_unregister_target(AF_INET6, &ip6t_standard_target); - xt_proto_fini(AF_INET6); +#ifdef CONFIG_PROC_FS + { + int i; + for (i = 0; ip6t_proc_entry[i].name; i++) + proc_net_remove(ip6t_proc_entry[i].name); + } +#endif } /* @@ -1506,6 +2128,10 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, EXPORT_SYMBOL(ip6t_register_table); EXPORT_SYMBOL(ip6t_unregister_table); EXPORT_SYMBOL(ip6t_do_table); +EXPORT_SYMBOL(ip6t_register_match); +EXPORT_SYMBOL(ip6t_unregister_match); +EXPORT_SYMBOL(ip6t_register_target); +EXPORT_SYMBOL(ip6t_unregister_target); EXPORT_SYMBOL(ip6t_ext_hdr); EXPORT_SYMBOL(ipv6_find_hdr); EXPORT_SYMBOL(ip6_masked_addrcmp); diff --git a/trunk/net/ipv6/netfilter/ip6t_HL.c b/trunk/net/ipv6/netfilter/ip6t_HL.c index 306200c35057..8f5549b72720 100644 --- a/trunk/net/ipv6/netfilter/ip6t_HL.c +++ b/trunk/net/ipv6/netfilter/ip6t_HL.c @@ -62,7 +62,7 @@ static unsigned int ip6t_hl_target(struct sk_buff **pskb, } static int ip6t_hl_checkentry(const char *tablename, - const void *entry, + const struct ip6t_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6t_LOG.c b/trunk/net/ipv6/netfilter/ip6t_LOG.c index 77c725832dec..ae4653bfd654 100644 --- a/trunk/net/ipv6/netfilter/ip6t_LOG.c +++ b/trunk/net/ipv6/netfilter/ip6t_LOG.c @@ -63,8 +63,9 @@ static void dump_packet(const struct nf_loginfo *info, return; } - /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */ - printk("SRC=" NIP6_FMT " DST=" NIP6_FMT " ", NIP6(ih->saddr), NIP6(ih->daddr)); + /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000" */ + printk("SRC=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ih->saddr)); + printk("DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", NIP6(ih->daddr)); /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", @@ -443,7 +444,7 @@ ip6t_log_target(struct sk_buff **pskb, static int ip6t_log_checkentry(const char *tablename, - const void *entry, + const struct ip6t_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6t_MARK.c b/trunk/net/ipv6/netfilter/ip6t_MARK.c new file mode 100644 index 000000000000..eab8fb864ee0 --- /dev/null +++ b/trunk/net/ipv6/netfilter/ip6t_MARK.c @@ -0,0 +1,81 @@ +/* This is a module which is used for setting the NFMARK field of an skb. */ + +/* (C) 1999-2001 Marc Boucher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + const struct ip6t_mark_target_info *markinfo = targinfo; + + if((*pskb)->nfmark != markinfo->mark) + (*pskb)->nfmark = markinfo->mark; + + return IP6T_CONTINUE; +} + +static int +checkentry(const char *tablename, + const struct ip6t_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))) { + printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", + targinfosize, + IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))); + return 0; + } + + if (strcmp(tablename, "mangle") != 0) { + printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); + return 0; + } + + return 1; +} + +static struct ip6t_target ip6t_mark_reg = { + .name = "MARK", + .target = target, + .checkentry = checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + printk(KERN_DEBUG "registering ipv6 mark target\n"); + if (ip6t_register_target(&ip6t_mark_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + ip6t_unregister_target(&ip6t_mark_reg); +} + +module_init(init); +module_exit(fini); diff --git a/trunk/net/ipv6/netfilter/ip6t_NFQUEUE.c b/trunk/net/ipv6/netfilter/ip6t_NFQUEUE.c new file mode 100644 index 000000000000..c6e3730e7409 --- /dev/null +++ b/trunk/net/ipv6/netfilter/ip6t_NFQUEUE.c @@ -0,0 +1,70 @@ +/* ip6tables module for using new netfilter netlink queue + * + * (C) 2005 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include + +#include +#include +#include + +MODULE_AUTHOR("Harald Welte "); +MODULE_DESCRIPTION("ip6tables NFQUEUE target"); +MODULE_LICENSE("GPL"); + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + const struct ipt_NFQ_info *tinfo = targinfo; + + return NF_QUEUE_NR(tinfo->queuenum); +} + +static int +checkentry(const char *tablename, + const struct ip6t_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + if (targinfosize != IP6T_ALIGN(sizeof(struct ipt_NFQ_info))) { + printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", + targinfosize, + IP6T_ALIGN(sizeof(struct ipt_NFQ_info))); + return 0; + } + + return 1; +} + +static struct ip6t_target ipt_NFQ_reg = { + .name = "NFQUEUE", + .target = target, + .checkentry = checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ip6t_register_target(&ipt_NFQ_reg); +} + +static void __exit fini(void) +{ + ip6t_unregister_target(&ipt_NFQ_reg); +} + +module_init(init); +module_exit(fini); diff --git a/trunk/net/ipv6/netfilter/ip6t_REJECT.c b/trunk/net/ipv6/netfilter/ip6t_REJECT.c index c745717b4ce2..b03e87adca93 100644 --- a/trunk/net/ipv6/netfilter/ip6t_REJECT.c +++ b/trunk/net/ipv6/netfilter/ip6t_REJECT.c @@ -218,13 +218,12 @@ static unsigned int reject6_target(struct sk_buff **pskb, } static int check(const char *tablename, - const void *entry, + const struct ip6t_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { const struct ip6t_reject_info *rejinfo = targinfo; - const struct ip6t_entry *e = entry; if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_reject_info))) { DEBUGP("ip6t_REJECT: targinfosize %u != 0\n", targinfosize); diff --git a/trunk/net/ipv6/netfilter/ip6t_ah.c b/trunk/net/ipv6/netfilter/ip6t_ah.c index 219a30365dff..f5c1a7ff4a1f 100644 --- a/trunk/net/ipv6/netfilter/ip6t_ah.c +++ b/trunk/net/ipv6/netfilter/ip6t_ah.c @@ -98,7 +98,7 @@ match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *entry, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6t_dst.c b/trunk/net/ipv6/netfilter/ip6t_dst.c index 80fe82669ce2..48cf5f9efc95 100644 --- a/trunk/net/ipv6/netfilter/ip6t_dst.c +++ b/trunk/net/ipv6/netfilter/ip6t_dst.c @@ -178,7 +178,7 @@ match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *info, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6t_esp.c b/trunk/net/ipv6/netfilter/ip6t_esp.c index 724285df8711..e1828f6d0a40 100644 --- a/trunk/net/ipv6/netfilter/ip6t_esp.c +++ b/trunk/net/ipv6/netfilter/ip6t_esp.c @@ -76,7 +76,7 @@ match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *ip, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6t_eui64.c b/trunk/net/ipv6/netfilter/ip6t_eui64.c index ddf5f571909c..616c2cbcd54d 100644 --- a/trunk/net/ipv6/netfilter/ip6t_eui64.c +++ b/trunk/net/ipv6/netfilter/ip6t_eui64.c @@ -62,7 +62,7 @@ match(const struct sk_buff *skb, static int ip6t_eui64_checkentry(const char *tablename, - const void *ip, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6t_frag.c b/trunk/net/ipv6/netfilter/ip6t_frag.c index a9964b946ed5..d1549b268669 100644 --- a/trunk/net/ipv6/netfilter/ip6t_frag.c +++ b/trunk/net/ipv6/netfilter/ip6t_frag.c @@ -115,7 +115,7 @@ match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *ip, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6t_hbh.c b/trunk/net/ipv6/netfilter/ip6t_hbh.c index ed8ded18bbd4..e3bc8e2700e7 100644 --- a/trunk/net/ipv6/netfilter/ip6t_hbh.c +++ b/trunk/net/ipv6/netfilter/ip6t_hbh.c @@ -178,7 +178,7 @@ match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *entry, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6t_hl.c b/trunk/net/ipv6/netfilter/ip6t_hl.c index c5d9079f2d9d..0beaff5471dd 100644 --- a/trunk/net/ipv6/netfilter/ip6t_hl.c +++ b/trunk/net/ipv6/netfilter/ip6t_hl.c @@ -48,7 +48,7 @@ static int match(const struct sk_buff *skb, const struct net_device *in, return 0; } -static int checkentry(const char *tablename, const void *entry, +static int checkentry(const char *tablename, const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { diff --git a/trunk/net/ipv6/netfilter/ip6t_ipv6header.c b/trunk/net/ipv6/netfilter/ip6t_ipv6header.c index fda1ceaf5a29..32e67f05845b 100644 --- a/trunk/net/ipv6/netfilter/ip6t_ipv6header.c +++ b/trunk/net/ipv6/netfilter/ip6t_ipv6header.c @@ -124,7 +124,7 @@ ipv6header_match(const struct sk_buff *skb, static int ipv6header_checkentry(const char *tablename, - const void *ip, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6t_length.c b/trunk/net/ipv6/netfilter/ip6t_length.c new file mode 100644 index 000000000000..e0537d3811d5 --- /dev/null +++ b/trunk/net/ipv6/netfilter/ip6t_length.c @@ -0,0 +1,66 @@ +/* Length Match - IPv6 Port */ + +/* (C) 1999-2001 James Morris + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + + +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("James Morris "); +MODULE_DESCRIPTION("IPv6 packet length match"); + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + const struct ip6t_length_info *info = matchinfo; + u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr); + + return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; +} + +static int +checkentry(const char *tablename, + const struct ip6t_ip6 *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_length_info))) + return 0; + + return 1; +} + +static struct ip6t_match length_match = { + .name = "length", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ip6t_register_match(&length_match); +} + +static void __exit fini(void) +{ + ip6t_unregister_match(&length_match); +} + +module_init(init); +module_exit(fini); diff --git a/trunk/net/ipv6/netfilter/ip6t_limit.c b/trunk/net/ipv6/netfilter/ip6t_limit.c new file mode 100644 index 000000000000..fb782f610be2 --- /dev/null +++ b/trunk/net/ipv6/netfilter/ip6t_limit.c @@ -0,0 +1,147 @@ +/* Kernel module to control the rate + * + * 2 September 1999: Changed from the target RATE to the match + * `limit', removed logging. Did I mention that + * Alexey is a fucking genius? + * Rusty Russell (rusty@rustcorp.com.au). */ + +/* (C) 1999 Jérôme de Vivie + * (C) 1999 Hervé Eychenne + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Herve Eychenne "); +MODULE_DESCRIPTION("rate limiting within ip6tables"); + +/* The algorithm used is the Simple Token Bucket Filter (TBF) + * see net/sched/sch_tbf.c in the linux source tree + */ + +static DEFINE_SPINLOCK(limit_lock); + +/* Rusty: This is my (non-mathematically-inclined) understanding of + this algorithm. The `average rate' in jiffies becomes your initial + amount of credit `credit' and the most credit you can ever have + `credit_cap'. The `peak rate' becomes the cost of passing the + test, `cost'. + + `prev' tracks the last packet hit: you gain one credit per jiffy. + If you get credit balance more than this, the extra credit is + discarded. Every time the match passes, you lose `cost' credits; + if you don't have that many, the test fails. + + See Alexey's formal explanation in net/sched/sch_tbf.c. + + To avoid underflow, we multiply by 128 (ie. you get 128 credits per + jiffy). Hence a cost of 2^32-1, means one pass per 32768 seconds + at 1024HZ (or one every 9 hours). A cost of 1 means 12800 passes + per second at 100HZ. */ + +#define CREDITS_PER_JIFFY 128 + +static int +ip6t_limit_match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + struct ip6t_rateinfo *r = ((struct ip6t_rateinfo *)matchinfo)->master; + unsigned long now = jiffies; + + spin_lock_bh(&limit_lock); + r->credit += (now - xchg(&r->prev, now)) * CREDITS_PER_JIFFY; + if (r->credit > r->credit_cap) + r->credit = r->credit_cap; + + if (r->credit >= r->cost) { + /* We're not limited. */ + r->credit -= r->cost; + spin_unlock_bh(&limit_lock); + return 1; + } + + spin_unlock_bh(&limit_lock); + return 0; +} + +/* Precision saver. */ +static u_int32_t +user2credits(u_int32_t user) +{ + /* If multiplying would overflow... */ + if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) + /* Divide first. */ + return (user / IP6T_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; + + return (user * HZ * CREDITS_PER_JIFFY) / IP6T_LIMIT_SCALE; +} + +static int +ip6t_limit_checkentry(const char *tablename, + const struct ip6t_ip6 *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + struct ip6t_rateinfo *r = matchinfo; + + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_rateinfo))) + return 0; + + /* Check for overflow. */ + if (r->burst == 0 + || user2credits(r->avg * r->burst) < user2credits(r->avg)) { + printk("Call rusty: overflow in ip6t_limit: %u/%u\n", + r->avg, r->burst); + return 0; + } + + /* User avg in seconds * IP6T_LIMIT_SCALE: convert to jiffies * + 128. */ + r->prev = jiffies; + r->credit = user2credits(r->avg * r->burst); /* Credits full. */ + r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */ + r->cost = user2credits(r->avg); + + /* For SMP, we only want to use one set of counters. */ + r->master = r; + + return 1; +} + +static struct ip6t_match ip6t_limit_reg = { + .name = "limit", + .match = ip6t_limit_match, + .checkentry = ip6t_limit_checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + if (ip6t_register_match(&ip6t_limit_reg)) + return -EINVAL; + return 0; +} + +static void __exit fini(void) +{ + ip6t_unregister_match(&ip6t_limit_reg); +} + +module_init(init); +module_exit(fini); diff --git a/trunk/net/ipv6/netfilter/ip6t_mac.c b/trunk/net/ipv6/netfilter/ip6t_mac.c new file mode 100644 index 000000000000..c848152315bc --- /dev/null +++ b/trunk/net/ipv6/netfilter/ip6t_mac.c @@ -0,0 +1,81 @@ +/* Kernel module to match MAC address parameters. */ + +/* (C) 1999-2001 Paul `Rusty' Russell + * (C) 2002-2004 Netfilter Core Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MAC address matching module for IPv6"); +MODULE_AUTHOR("Netfilter Core Teaam "); + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + const struct ip6t_mac_info *info = matchinfo; + + /* Is mac pointer valid? */ + return (skb->mac.raw >= skb->head + && (skb->mac.raw + ETH_HLEN) <= skb->data + /* If so, compare... */ + && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr)) + ^ info->invert)); +} + +static int +ip6t_mac_checkentry(const char *tablename, + const struct ip6t_ip6 *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (hook_mask + & ~((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) + | (1 << NF_IP6_FORWARD))) { + printk("ip6t_mac: only valid for PRE_ROUTING, LOCAL_IN or" + " FORWARD\n"); + return 0; + } + + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mac_info))) + return 0; + + return 1; +} + +static struct ip6t_match mac_match = { + .name = "mac", + .match = &match, + .checkentry = &ip6t_mac_checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ip6t_register_match(&mac_match); +} + +static void __exit fini(void) +{ + ip6t_unregister_match(&mac_match); +} + +module_init(init); +module_exit(fini); diff --git a/trunk/net/ipv6/netfilter/ip6t_mark.c b/trunk/net/ipv6/netfilter/ip6t_mark.c new file mode 100644 index 000000000000..affc3de364fc --- /dev/null +++ b/trunk/net/ipv6/netfilter/ip6t_mark.c @@ -0,0 +1,66 @@ +/* Kernel module to match NFMARK values. */ + +/* (C) 1999-2001 Marc Boucher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + + +#include +#include + +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Netfilter Core Team "); +MODULE_DESCRIPTION("ip6tables mark match"); + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + unsigned int protoff, + int *hotdrop) +{ + const struct ip6t_mark_info *info = matchinfo; + + return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; +} + +static int +checkentry(const char *tablename, + const struct ip6t_ip6 *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mark_info))) + return 0; + + return 1; +} + +static struct ip6t_match mark_match = { + .name = "mark", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + return ip6t_register_match(&mark_match); +} + +static void __exit fini(void) +{ + ip6t_unregister_match(&mark_match); +} + +module_init(init); +module_exit(fini); diff --git a/trunk/net/ipv6/netfilter/ip6t_multiport.c b/trunk/net/ipv6/netfilter/ip6t_multiport.c index 49f7829dfbc2..6e3246153fa3 100644 --- a/trunk/net/ipv6/netfilter/ip6t_multiport.c +++ b/trunk/net/ipv6/netfilter/ip6t_multiport.c @@ -84,12 +84,11 @@ match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *info, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - const struct ip6t_ip6 *ip = info; const struct ip6t_multiport *multiinfo = matchinfo; if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_multiport))) diff --git a/trunk/net/ipv6/netfilter/ip6t_owner.c b/trunk/net/ipv6/netfilter/ip6t_owner.c index 5409b375b512..4de4cdad4b7d 100644 --- a/trunk/net/ipv6/netfilter/ip6t_owner.c +++ b/trunk/net/ipv6/netfilter/ip6t_owner.c @@ -53,7 +53,7 @@ match(const struct sk_buff *skb, static int checkentry(const char *tablename, - const void *ip, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) diff --git a/trunk/net/netfilter/xt_physdev.c b/trunk/net/ipv6/netfilter/ip6t_physdev.c similarity index 57% rename from trunk/net/netfilter/xt_physdev.c rename to trunk/net/ipv6/netfilter/ip6t_physdev.c index 19bb57c14dfe..71515c86ece1 100644 --- a/trunk/net/netfilter/xt_physdev.c +++ b/trunk/net/ipv6/netfilter/ip6t_physdev.c @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include #include #define MATCH 1 #define NOMATCH 0 @@ -19,8 +19,6 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Bart De Schuymer "); MODULE_DESCRIPTION("iptables bridge physical device match module"); -MODULE_ALIAS("ipt_physdev"); -MODULE_ALIAS("ip6t_physdev"); static int match(const struct sk_buff *skb, @@ -33,7 +31,7 @@ match(const struct sk_buff *skb, { int i; static const char nulldevname[IFNAMSIZ]; - const struct xt_physdev_info *info = matchinfo; + const struct ip6t_physdev_info *info = matchinfo; unsigned int ret; const char *indev, *outdev; struct nf_bridge_info *nf_bridge; @@ -43,37 +41,37 @@ match(const struct sk_buff *skb, * the destination device will be a bridge. */ if (!(nf_bridge = skb->nf_bridge)) { /* Return MATCH if the invert flags of the used options are on */ - if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && - !(info->invert & XT_PHYSDEV_OP_BRIDGED)) + if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) && + !(info->invert & IP6T_PHYSDEV_OP_BRIDGED)) return NOMATCH; - if ((info->bitmask & XT_PHYSDEV_OP_ISIN) && - !(info->invert & XT_PHYSDEV_OP_ISIN)) + if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN) && + !(info->invert & IP6T_PHYSDEV_OP_ISIN)) return NOMATCH; - if ((info->bitmask & XT_PHYSDEV_OP_ISOUT) && - !(info->invert & XT_PHYSDEV_OP_ISOUT)) + if ((info->bitmask & IP6T_PHYSDEV_OP_ISOUT) && + !(info->invert & IP6T_PHYSDEV_OP_ISOUT)) return NOMATCH; - if ((info->bitmask & XT_PHYSDEV_OP_IN) && - !(info->invert & XT_PHYSDEV_OP_IN)) + if ((info->bitmask & IP6T_PHYSDEV_OP_IN) && + !(info->invert & IP6T_PHYSDEV_OP_IN)) return NOMATCH; - if ((info->bitmask & XT_PHYSDEV_OP_OUT) && - !(info->invert & XT_PHYSDEV_OP_OUT)) + if ((info->bitmask & IP6T_PHYSDEV_OP_OUT) && + !(info->invert & IP6T_PHYSDEV_OP_OUT)) return NOMATCH; return MATCH; } /* This only makes sense in the FORWARD and POSTROUTING chains */ - if ((info->bitmask & XT_PHYSDEV_OP_BRIDGED) && + if ((info->bitmask & IP6T_PHYSDEV_OP_BRIDGED) && (!!(nf_bridge->mask & BRNF_BRIDGED) ^ - !(info->invert & XT_PHYSDEV_OP_BRIDGED))) + !(info->invert & IP6T_PHYSDEV_OP_BRIDGED))) return NOMATCH; - if ((info->bitmask & XT_PHYSDEV_OP_ISIN && - (!nf_bridge->physindev ^ !!(info->invert & XT_PHYSDEV_OP_ISIN))) || - (info->bitmask & XT_PHYSDEV_OP_ISOUT && - (!nf_bridge->physoutdev ^ !!(info->invert & XT_PHYSDEV_OP_ISOUT)))) + if ((info->bitmask & IP6T_PHYSDEV_OP_ISIN && + (!nf_bridge->physindev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISIN))) || + (info->bitmask & IP6T_PHYSDEV_OP_ISOUT && + (!nf_bridge->physoutdev ^ !!(info->invert & IP6T_PHYSDEV_OP_ISOUT)))) return NOMATCH; - if (!(info->bitmask & XT_PHYSDEV_OP_IN)) + if (!(info->bitmask & IP6T_PHYSDEV_OP_IN)) goto match_outdev; indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned int); i++) { @@ -82,11 +80,11 @@ match(const struct sk_buff *skb, & ((const unsigned int *)info->in_mask)[i]; } - if ((ret == 0) ^ !(info->invert & XT_PHYSDEV_OP_IN)) + if ((ret == 0) ^ !(info->invert & IP6T_PHYSDEV_OP_IN)) return NOMATCH; match_outdev: - if (!(info->bitmask & XT_PHYSDEV_OP_OUT)) + if (!(info->bitmask & IP6T_PHYSDEV_OP_OUT)) return MATCH; outdev = nf_bridge->physoutdev ? nf_bridge->physoutdev->name : nulldevname; @@ -96,34 +94,27 @@ match(const struct sk_buff *skb, & ((const unsigned int *)info->out_mask)[i]; } - return (ret != 0) ^ !(info->invert & XT_PHYSDEV_OP_OUT); + return (ret != 0) ^ !(info->invert & IP6T_PHYSDEV_OP_OUT); } static int checkentry(const char *tablename, - const void *ip, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchsize, unsigned int hook_mask) { - const struct xt_physdev_info *info = matchinfo; + const struct ip6t_physdev_info *info = matchinfo; - if (matchsize != XT_ALIGN(sizeof(struct xt_physdev_info))) + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_physdev_info))) return 0; - if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || - info->bitmask & ~XT_PHYSDEV_OP_MASK) + if (!(info->bitmask & IP6T_PHYSDEV_OP_MASK) || + info->bitmask & ~IP6T_PHYSDEV_OP_MASK) return 0; return 1; } -static struct xt_match physdev_match = { - .name = "physdev", - .match = &match, - .checkentry = &checkentry, - .me = THIS_MODULE, -}; - -static struct xt_match physdev6_match = { +static struct ip6t_match physdev_match = { .name = "physdev", .match = &match, .checkentry = &checkentry, @@ -132,23 +123,12 @@ static struct xt_match physdev6_match = { static int __init init(void) { - int ret; - - ret = xt_register_match(AF_INET, &physdev_match); - if (ret < 0) - return ret; - - ret = xt_register_match(AF_INET6, &physdev6_match); - if (ret < 0) - xt_unregister_match(AF_INET, &physdev_match); - - return ret; + return ip6t_register_match(&physdev_match); } static void __exit fini(void) { - xt_unregister_match(AF_INET, &physdev_match); - xt_unregister_match(AF_INET6, &physdev6_match); + ip6t_unregister_match(&physdev_match); } module_init(init); diff --git a/trunk/net/ipv6/netfilter/ip6t_rt.c b/trunk/net/ipv6/netfilter/ip6t_rt.c index 8465b4375855..c1e770e45543 100644 --- a/trunk/net/ipv6/netfilter/ip6t_rt.c +++ b/trunk/net/ipv6/netfilter/ip6t_rt.c @@ -183,7 +183,7 @@ match(const struct sk_buff *skb, /* Called when user tries to insert an entry of this type. */ static int checkentry(const char *tablename, - const void *entry, + const struct ip6t_ip6 *ip, void *matchinfo, unsigned int matchinfosize, unsigned int hook_mask) diff --git a/trunk/net/ipv6/netfilter/ip6table_filter.c b/trunk/net/ipv6/netfilter/ip6table_filter.c index ce4a968e1f70..4c0028671c20 100644 --- a/trunk/net/ipv6/netfilter/ip6table_filter.c +++ b/trunk/net/ipv6/netfilter/ip6table_filter.c @@ -97,7 +97,6 @@ static struct ip6t_table packet_filter = { .valid_hooks = FILTER_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, .me = THIS_MODULE, - .af = AF_INET6, }; /* The work comes in here from netfilter.c. */ diff --git a/trunk/net/ipv6/netfilter/ip6table_mangle.c b/trunk/net/ipv6/netfilter/ip6table_mangle.c index 30a4627e000d..85c1e6eada19 100644 --- a/trunk/net/ipv6/netfilter/ip6table_mangle.c +++ b/trunk/net/ipv6/netfilter/ip6table_mangle.c @@ -127,7 +127,6 @@ static struct ip6t_table packet_mangler = { .valid_hooks = MANGLE_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, .me = THIS_MODULE, - .af = AF_INET6, }; /* The work comes in here from netfilter.c. */ diff --git a/trunk/net/ipv6/netfilter/ip6table_raw.c b/trunk/net/ipv6/netfilter/ip6table_raw.c index db28ba3855e2..c2982efd14af 100644 --- a/trunk/net/ipv6/netfilter/ip6table_raw.c +++ b/trunk/net/ipv6/netfilter/ip6table_raw.c @@ -106,12 +106,11 @@ static struct } }; -static struct xt_table packet_raw = { +static struct ip6t_table packet_raw = { .name = "raw", .valid_hooks = RAW_VALID_HOOKS, .lock = RW_LOCK_UNLOCKED, - .me = THIS_MODULE, - .af = AF_INET6, + .me = THIS_MODULE }; /* The work comes in here from netfilter.c. */ diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index ac702a29dd16..e57d6fc9957a 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -74,7 +74,7 @@ static int ipv6_invert_tuple(struct nf_conntrack_tuple *tuple, static int ipv6_print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple) { - return seq_printf(s, "src=" NIP6_FMT " dst=" NIP6_FMT " ", + return seq_printf(s, "src=%x:%x:%x:%x:%x:%x:%x:%x dst=%x:%x:%x:%x:%x:%x:%x:%x ", NIP6(*((struct in6_addr *)tuple->src.u3.ip6)), NIP6(*((struct in6_addr *)tuple->dst.u3.ip6))); } @@ -584,7 +584,7 @@ MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI "); static int __init init(void) { - need_conntrack(); + need_nf_conntrack(); return init_or_cleanup(1); } @@ -595,3 +595,9 @@ static void __exit fini(void) module_init(init); module_exit(fini); + +void need_ip6_conntrack(void) +{ +} + +EXPORT_SYMBOL(need_ip6_conntrack); diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index 84ef9a13108d..f3e5ffbd592f 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -70,8 +70,8 @@ struct nf_ct_frag6_skb_cb struct nf_ct_frag6_queue { - struct hlist_node list; - struct list_head lru_list; /* lru list member */ + struct nf_ct_frag6_queue *next; + struct list_head lru_list; /* lru list member */ __u32 id; /* fragment id */ struct in6_addr saddr; @@ -90,13 +90,14 @@ struct nf_ct_frag6_queue #define FIRST_IN 2 #define LAST_IN 1 __u16 nhoffset; + struct nf_ct_frag6_queue **pprev; }; /* Hash table. */ #define FRAG6Q_HASHSZ 64 -static struct hlist_head nf_ct_frag6_hash[FRAG6Q_HASHSZ]; +static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ]; static DEFINE_RWLOCK(nf_ct_frag6_lock); static u32 nf_ct_frag6_hash_rnd; static LIST_HEAD(nf_ct_frag6_lru_list); @@ -104,7 +105,9 @@ int nf_ct_frag6_nqueues = 0; static __inline__ void __fq_unlink(struct nf_ct_frag6_queue *fq) { - hlist_del(&fq->list); + if (fq->next) + fq->next->pprev = fq->pprev; + *fq->pprev = fq->next; list_del(&fq->lru_list); nf_ct_frag6_nqueues--; } @@ -155,18 +158,28 @@ static void nf_ct_frag6_secret_rebuild(unsigned long dummy) get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32)); for (i = 0; i < FRAG6Q_HASHSZ; i++) { struct nf_ct_frag6_queue *q; - struct hlist_node *p, *n; - hlist_for_each_entry_safe(q, p, n, &nf_ct_frag6_hash[i], list) { + q = nf_ct_frag6_hash[i]; + while (q) { + struct nf_ct_frag6_queue *next = q->next; unsigned int hval = ip6qhashfn(q->id, &q->saddr, &q->daddr); + if (hval != i) { - hlist_del(&q->list); + /* Unlink. */ + if (q->next) + q->next->pprev = q->pprev; + *q->pprev = q->next; + /* Relink to new hash chain. */ - hlist_add_head(&q->list, - &nf_ct_frag6_hash[hval]); + if ((q->next = nf_ct_frag6_hash[hval]) != NULL) + q->next->pprev = &q->next; + nf_ct_frag6_hash[hval] = q; + q->pprev = &nf_ct_frag6_hash[hval]; } + + q = next; } } write_unlock(&nf_ct_frag6_lock); @@ -301,17 +314,15 @@ static void nf_ct_frag6_expire(unsigned long data) /* Creation primitives. */ + static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, struct nf_ct_frag6_queue *fq_in) { struct nf_ct_frag6_queue *fq; -#ifdef CONFIG_SMP - struct hlist_node *n; -#endif write_lock(&nf_ct_frag6_lock); #ifdef CONFIG_SMP - hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) { + for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) { if (fq->id == fq_in->id && !ipv6_addr_cmp(&fq_in->saddr, &fq->saddr) && !ipv6_addr_cmp(&fq_in->daddr, &fq->daddr)) { @@ -329,7 +340,10 @@ static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, atomic_inc(&fq->refcnt); atomic_inc(&fq->refcnt); - hlist_add_head(&fq->list, &nf_ct_frag6_hash[hash]); + if ((fq->next = nf_ct_frag6_hash[hash]) != NULL) + fq->next->pprev = &fq->next; + nf_ct_frag6_hash[hash] = fq; + fq->pprev = &nf_ct_frag6_hash[hash]; INIT_LIST_HEAD(&fq->lru_list); list_add_tail(&fq->lru_list, &nf_ct_frag6_lru_list); nf_ct_frag6_nqueues++; @@ -370,11 +384,10 @@ static __inline__ struct nf_ct_frag6_queue * fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) { struct nf_ct_frag6_queue *fq; - struct hlist_node *n; unsigned int hash = ip6qhashfn(id, src, dst); read_lock(&nf_ct_frag6_lock); - hlist_for_each_entry(fq, n, &nf_ct_frag6_hash[hash], list) { + for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) { if (fq->id == id && !ipv6_addr_cmp(src, &fq->saddr) && !ipv6_addr_cmp(dst, &fq->daddr)) { diff --git a/trunk/net/ipv6/xfrm6_state.c b/trunk/net/ipv6/xfrm6_state.c index a5723024d3b3..bf0d0abc3871 100644 --- a/trunk/net/ipv6/xfrm6_state.c +++ b/trunk/net/ipv6/xfrm6_state.c @@ -15,7 +15,6 @@ #include #include #include -#include static struct xfrm_state_afinfo xfrm6_state_afinfo; @@ -42,22 +41,6 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr)); if (ipv6_addr_any((struct in6_addr*)&x->props.saddr)) memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr)); - if (tmpl->mode && ipv6_addr_any((struct in6_addr*)&x->props.saddr)) { - struct rt6_info *rt; - struct flowi fl_tunnel = { - .nl_u = { - .ip6_u = { - .daddr = *(struct in6_addr *)daddr, - } - } - }; - if (!xfrm_dst_lookup((struct xfrm_dst **)&rt, - &fl_tunnel, AF_INET6)) { - ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)daddr, - (struct in6_addr *)&x->props.saddr); - dst_release(&rt->u.dst); - } - } x->props.mode = tmpl->mode; x->props.reqid = tmpl->reqid; x->props.family = AF_INET6; diff --git a/trunk/net/ipv6/xfrm6_tunnel.c b/trunk/net/ipv6/xfrm6_tunnel.c index 8cfc58b96fc2..da09ff258648 100644 --- a/trunk/net/ipv6/xfrm6_tunnel.c +++ b/trunk/net/ipv6/xfrm6_tunnel.c @@ -259,7 +259,8 @@ try_next_2:; spi = 0; goto out; alloc_spi: - X6TPRINTK3(KERN_DEBUG "%s(): allocate new spi for " NIP6_FMT "\n", + X6TPRINTK3(KERN_DEBUG "%s(): allocate new spi for " + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", __FUNCTION__, NIP6(*(struct in6_addr *)saddr)); x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC); @@ -322,8 +323,9 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr) list_byaddr) { if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) { - X6TPRINTK3(KERN_DEBUG "%s(): x6spi object for " NIP6_FMT - " found at %p\n", + X6TPRINTK3(KERN_DEBUG "%s(): x6spi object " + "for %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x " + "found at %p\n", __FUNCTION__, NIP6(*(struct in6_addr *)saddr), x6spi); diff --git a/trunk/net/netfilter/Kconfig b/trunk/net/netfilter/Kconfig index 99c0a0fa4a97..7d55f9cbd853 100644 --- a/trunk/net/netfilter/Kconfig +++ b/trunk/net/netfilter/Kconfig @@ -103,261 +103,3 @@ config NF_CT_NETLINK This option enables support for a netlink-based userspace interface endmenu - -config NETFILTER_XTABLES - tristate "Netfilter Xtables support (required for ip_tables)" - help - This is required if you intend to use any of ip_tables, - ip6_tables or arp_tables. - -# alphabetically ordered list of targets - -config NETFILTER_XT_TARGET_CLASSIFY - tristate '"CLASSIFY" target support' - depends on NETFILTER_XTABLES - help - This option adds a `CLASSIFY' target, which enables the user to set - the priority of a packet. Some qdiscs can use this value for - classification, among these are: - - atm, cbq, dsmark, pfifo_fast, htb, prio - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_TARGET_CONNMARK - tristate '"CONNMARK" target support' - depends on NETFILTER_XTABLES - depends on IP_NF_MANGLE || IP6_NF_MANGLE - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) - help - This option adds a `CONNMARK' target, which allows one to manipulate - the connection mark value. Similar to the MARK target, but - affects the connection mark value rather than the packet mark value. - - If you want to compile it as a module, say M here and read - . The module will be called - ipt_CONNMARK.o. If unsure, say `N'. - -config NETFILTER_XT_TARGET_MARK - tristate '"MARK" target support' - depends on NETFILTER_XTABLES - help - This option adds a `MARK' target, which allows you to create rules - in the `mangle' table which alter the netfilter mark (nfmark) field - associated with the packet prior to routing. This can change - the routing method (see `Use netfilter MARK value as routing - key') and can also be used by other subsystems to change their - behavior. - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_TARGET_NFQUEUE - tristate '"NFQUEUE" target Support' - depends on NETFILTER_XTABLES - help - This Target replaced the old obsolete QUEUE target. - - As opposed to QUEUE, it supports 65535 different queues, - not just one. - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_TARGET_NOTRACK - tristate '"NOTRACK" target support' - depends on NETFILTER_XTABLES - depends on IP_NF_RAW || IP6_NF_RAW - depends on IP_NF_CONNTRACK || NF_CONNTRACK - help - The NOTRACK target allows a select rule to specify - which packets *not* to enter the conntrack/NAT - subsystem with all the consequences (no ICMP error tracking, - no protocol helpers for the selected packets). - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - -config NETFILTER_XT_MATCH_COMMENT - tristate '"comment" match support' - depends on NETFILTER_XTABLES - help - This option adds a `comment' dummy-match, which allows you to put - comments in your iptables ruleset. - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - -config NETFILTER_XT_MATCH_CONNBYTES - tristate '"connbytes" per-connection counter match support' - depends on NETFILTER_XTABLES - depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || NF_CT_ACCT - help - This option adds a `connbytes' match, which allows you to match the - number of bytes and/or packets for each direction within a connection. - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - -config NETFILTER_XT_MATCH_CONNMARK - tristate '"connmark" connection mark match support' - depends on NETFILTER_XTABLES - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || NF_CONNTRACK_MARK - help - This option adds a `connmark' match, which allows you to match the - connection mark value previously set for the session by `CONNMARK'. - - If you want to compile it as a module, say M here and read - . The module will be called - ipt_connmark.o. If unsure, say `N'. - -config NETFILTER_XT_MATCH_CONNTRACK - tristate '"conntrack" connection tracking match support' - depends on NETFILTER_XTABLES - depends on IP_NF_CONNTRACK || NF_CONNTRACK - help - This is a general conntrack match module, a superset of the state match. - - It allows matching on additional conntrack information, which is - useful in complex configurations, such as NAT gateways with multiple - internet links or tunnels. - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_MATCH_DCCP - tristate '"DCCP" protocol match support' - depends on NETFILTER_XTABLES - help - With this option enabled, you will be able to use the iptables - `dccp' match in order to match on DCCP source/destination ports - and DCCP flags. - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - -config NETFILTER_XT_MATCH_HELPER - tristate '"helper" match support' - depends on NETFILTER_XTABLES - depends on IP_NF_CONNTRACK || NF_CONNTRACK - help - Helper matching allows you to match packets in dynamic connections - tracked by a conntrack-helper, ie. ip_conntrack_ftp - - To compile it as a module, choose M here. If unsure, say Y. - -config NETFILTER_XT_MATCH_LENGTH - tristate '"length" match support' - depends on NETFILTER_XTABLES - help - This option allows you to match the length of a packet against a - specific value or range of values. - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_MATCH_LIMIT - tristate '"limit" match support' - depends on NETFILTER_XTABLES - help - limit matching allows you to control the rate at which a rule can be - matched: mainly useful in combination with the LOG target ("LOG - target support", below) and to avoid some Denial of Service attacks. - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_MATCH_MAC - tristate '"mac" address match support' - depends on NETFILTER_XTABLES - help - MAC matching allows you to match packets based on the source - Ethernet address of the packet. - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_MATCH_MARK - tristate '"mark" match support' - depends on NETFILTER_XTABLES - help - Netfilter mark matching allows you to match packets based on the - `nfmark' value in the packet. This can be set by the MARK target - (see below). - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_MATCH_PHYSDEV - tristate '"physdev" match support' - depends on NETFILTER_XTABLES && BRIDGE_NETFILTER - help - Physdev packet matching matches against the physical bridge ports - the IP packet arrived on or will leave by. - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_MATCH_PKTTYPE - tristate '"pkttype" packet type match support' - depends on NETFILTER_XTABLES - help - Packet type matching allows you to match a packet by - its "class", eg. BROADCAST, MULTICAST, ... - - Typical usage: - iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_MATCH_REALM - tristate '"realm" match support' - depends on NETFILTER_XTABLES - select NET_CLS_ROUTE - help - This option adds a `realm' match, which allows you to use the realm - key from the routing subsystem inside iptables. - - This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option - in tc world. - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - -config NETFILTER_XT_MATCH_SCTP - tristate '"sctp" protocol match support' - depends on NETFILTER_XTABLES - help - With this option enabled, you will be able to use the - `sctp' match in order to match on SCTP source/destination ports - and SCTP chunk types. - - If you want to compile it as a module, say M here and read - . If unsure, say `N'. - -config NETFILTER_XT_MATCH_STATE - tristate '"state" match support' - depends on NETFILTER_XTABLES - depends on IP_NF_CONNTRACK || NF_CONNTRACK - help - Connection state matching allows you to match packets based on their - relationship to a tracked connection (ie. previous packets). This - is a powerful tool for packet classification. - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_MATCH_STRING - tristate '"string" match support' - depends on NETFILTER_XTABLES - select TEXTSEARCH - select TEXTSEARCH_KMP - select TEXTSEARCH_BM - select TEXTSEARCH_FSM - help - This option adds a `string' match, which allows you to look for - pattern matchings in packets. - - To compile it as a module, choose M here. If unsure, say N. - -config NETFILTER_XT_MATCH_TCPMSS - tristate '"tcpmss" match support' - depends on NETFILTER_XTABLES - help - This option adds a `tcpmss' match, which allows you to examine the - MSS value of TCP SYN packets, which control the maximum packet size - for that connection. - - To compile it as a module, choose M here. If unsure, say N. - diff --git a/trunk/net/netfilter/Makefile b/trunk/net/netfilter/Makefile index 746172ebc91b..cb2183145c37 100644 --- a/trunk/net/netfilter/Makefile +++ b/trunk/net/netfilter/Makefile @@ -1,5 +1,4 @@ netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o -nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o obj-$(CONFIG_NETFILTER) = netfilter.o @@ -7,43 +6,13 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o -# connection tracking +nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o + obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o +obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o # SCTP protocol connection tracking obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o # netlink interface for nf_conntrack obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o - -# connection tracking helpers -obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o - -# generic X tables -obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o - -# targets -obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o -obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o -obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o -obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o -obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o - -# matches -obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o -obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o -obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o -obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o -obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o -obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o -obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o -obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o -obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o -obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o -obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o -obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o -obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o -obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o -obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o -obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o -obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o diff --git a/trunk/net/netfilter/nf_conntrack_ftp.c b/trunk/net/netfilter/nf_conntrack_ftp.c index ab0c920f0d30..d5a6eaf4a1de 100644 --- a/trunk/net/netfilter/nf_conntrack_ftp.c +++ b/trunk/net/netfilter/nf_conntrack_ftp.c @@ -545,11 +545,11 @@ static int help(struct sk_buff **pskb, different IP address. Simply don't record it for NAT. */ if (cmd.l3num == PF_INET) { - DEBUGP("conntrack_ftp: NOT RECORDING: " NIPQUAD_FMT " != " NIPQUAD_FMT "\n", + DEBUGP("conntrack_ftp: NOT RECORDING: %u,%u,%u,%u != %u.%u.%u.%u\n", NIPQUAD(cmd.u3.ip), NIPQUAD(ct->tuplehash[dir].tuple.src.u3.ip)); } else { - DEBUGP("conntrack_ftp: NOT RECORDING: " NIP6_FMT " != " NIP6_FMT "\n", + DEBUGP("conntrack_ftp: NOT RECORDING: %x:%x:%x:%x:%x:%x:%x:%x != %x:%x:%x:%x:%x:%x:%x:%x\n", NIP6(*((struct in6_addr *)cmd.u3.ip6)), NIP6(*((struct in6_addr *)ct->tuplehash[dir] .tuple.src.u3.ip6))); diff --git a/trunk/net/netfilter/nf_conntrack_standalone.c b/trunk/net/netfilter/nf_conntrack_standalone.c index 617599aeeead..3531d142f693 100644 --- a/trunk/net/netfilter/nf_conntrack_standalone.c +++ b/trunk/net/netfilter/nf_conntrack_standalone.c @@ -821,7 +821,7 @@ module_exit(fini); /* Some modules need us, but don't depend directly on any symbol. They should call this. */ -void need_conntrack(void) +void need_nf_conntrack(void) { } @@ -841,7 +841,7 @@ EXPORT_SYMBOL(nf_conntrack_protocol_unregister); EXPORT_SYMBOL(nf_ct_invert_tuplepr); EXPORT_SYMBOL(nf_conntrack_alter_reply); EXPORT_SYMBOL(nf_conntrack_destroyed); -EXPORT_SYMBOL(need_conntrack); +EXPORT_SYMBOL(need_nf_conntrack); EXPORT_SYMBOL(nf_conntrack_helper_register); EXPORT_SYMBOL(nf_conntrack_helper_unregister); EXPORT_SYMBOL(nf_ct_iterate_cleanup); diff --git a/trunk/net/netfilter/x_tables.c b/trunk/net/netfilter/x_tables.c deleted file mode 100644 index d7817afc6b96..000000000000 --- a/trunk/net/netfilter/x_tables.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * x_tables core - Backend for {ip,ip6,arp}_tables - * - * Copyright (C) 2006-2006 Harald Welte - * - * Based on existing ip_tables code which is - * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling - * Copyright (C) 2000-2005 Netfilter Core Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module"); - -#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) - -struct xt_af { - struct semaphore mutex; - struct list_head match; - struct list_head target; - struct list_head tables; -}; - -static struct xt_af *xt; - -#ifdef DEBUG_IP_FIREWALL_USER -#define duprintf(format, args...) printk(format , ## args) -#else -#define duprintf(format, args...) -#endif - -enum { - TABLE, - TARGET, - MATCH, -}; - -/* Registration hooks for targets. */ -int -xt_register_target(int af, struct xt_target *target) -{ - int ret; - - ret = down_interruptible(&xt[af].mutex); - if (ret != 0) - return ret; - list_add(&target->list, &xt[af].target); - up(&xt[af].mutex); - return ret; -} -EXPORT_SYMBOL(xt_register_target); - -void -xt_unregister_target(int af, struct xt_target *target) -{ - down(&xt[af].mutex); - LIST_DELETE(&xt[af].target, target); - up(&xt[af].mutex); -} -EXPORT_SYMBOL(xt_unregister_target); - -int -xt_register_match(int af, struct xt_match *match) -{ - int ret; - - ret = down_interruptible(&xt[af].mutex); - if (ret != 0) - return ret; - - list_add(&match->list, &xt[af].match); - up(&xt[af].mutex); - - return ret; -} -EXPORT_SYMBOL(xt_register_match); - -void -xt_unregister_match(int af, struct xt_match *match) -{ - down(&xt[af].mutex); - LIST_DELETE(&xt[af].match, match); - up(&xt[af].mutex); -} -EXPORT_SYMBOL(xt_unregister_match); - - -/* - * These are weird, but module loading must not be done with mutex - * held (since they will register), and we have to have a single - * function to use try_then_request_module(). - */ - -/* Find match, grabs ref. Returns ERR_PTR() on error. */ -struct xt_match *xt_find_match(int af, const char *name, u8 revision) -{ - struct xt_match *m; - int err = 0; - - if (down_interruptible(&xt[af].mutex) != 0) - return ERR_PTR(-EINTR); - - list_for_each_entry(m, &xt[af].match, list) { - if (strcmp(m->name, name) == 0) { - if (m->revision == revision) { - if (try_module_get(m->me)) { - up(&xt[af].mutex); - return m; - } - } else - err = -EPROTOTYPE; /* Found something. */ - } - } - up(&xt[af].mutex); - return ERR_PTR(err); -} -EXPORT_SYMBOL(xt_find_match); - -/* Find target, grabs ref. Returns ERR_PTR() on error. */ -struct xt_target *xt_find_target(int af, const char *name, u8 revision) -{ - struct xt_target *t; - int err = 0; - - if (down_interruptible(&xt[af].mutex) != 0) - return ERR_PTR(-EINTR); - - list_for_each_entry(t, &xt[af].target, list) { - if (strcmp(t->name, name) == 0) { - if (t->revision == revision) { - if (try_module_get(t->me)) { - up(&xt[af].mutex); - return t; - } - } else - err = -EPROTOTYPE; /* Found something. */ - } - } - up(&xt[af].mutex); - return ERR_PTR(err); -} -EXPORT_SYMBOL(xt_find_target); - -static const char *xt_prefix[NPROTO] = { - [AF_INET] = "ipt_%s", - [AF_INET6] = "ip6t_%s", - [NF_ARP] = "arpt_%s", -}; - -struct xt_target *xt_request_find_target(int af, const char *name, u8 revision) -{ - struct xt_target *target; - - target = try_then_request_module(xt_find_target(af, name, revision), - xt_prefix[af], name); - if (IS_ERR(target) || !target) - return NULL; - return target; -} -EXPORT_SYMBOL_GPL(xt_request_find_target); - -static int match_revfn(int af, const char *name, u8 revision, int *bestp) -{ - struct xt_match *m; - int have_rev = 0; - - list_for_each_entry(m, &xt[af].match, list) { - if (strcmp(m->name, name) == 0) { - if (m->revision > *bestp) - *bestp = m->revision; - if (m->revision == revision) - have_rev = 1; - } - } - return have_rev; -} - -static int target_revfn(int af, const char *name, u8 revision, int *bestp) -{ - struct xt_target *t; - int have_rev = 0; - - list_for_each_entry(t, &xt[af].target, list) { - if (strcmp(t->name, name) == 0) { - if (t->revision > *bestp) - *bestp = t->revision; - if (t->revision == revision) - have_rev = 1; - } - } - return have_rev; -} - -/* Returns true or false (if no such extension at all) */ -int xt_find_revision(int af, const char *name, u8 revision, int target, - int *err) -{ - int have_rev, best = -1; - - if (down_interruptible(&xt[af].mutex) != 0) { - *err = -EINTR; - return 1; - } - if (target == 1) - have_rev = target_revfn(af, name, revision, &best); - else - have_rev = match_revfn(af, name, revision, &best); - up(&xt[af].mutex); - - /* Nothing at all? Return 0 to try loading module. */ - if (best == -1) { - *err = -ENOENT; - return 0; - } - - *err = best; - if (!have_rev) - *err = -EPROTONOSUPPORT; - return 1; -} -EXPORT_SYMBOL_GPL(xt_find_revision); - -struct xt_table_info *xt_alloc_table_info(unsigned int size) -{ - struct xt_table_info *newinfo; - int cpu; - - /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */ - if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > num_physpages) - return NULL; - - newinfo = kzalloc(sizeof(struct xt_table_info), GFP_KERNEL); - if (!newinfo) - return NULL; - - newinfo->size = size; - - for_each_cpu(cpu) { - if (size <= PAGE_SIZE) - newinfo->entries[cpu] = kmalloc_node(size, - GFP_KERNEL, - cpu_to_node(cpu)); - else - newinfo->entries[cpu] = vmalloc_node(size, - cpu_to_node(cpu)); - - if (newinfo->entries[cpu] == NULL) { - xt_free_table_info(newinfo); - return NULL; - } - } - - return newinfo; -} -EXPORT_SYMBOL(xt_alloc_table_info); - -void xt_free_table_info(struct xt_table_info *info) -{ - int cpu; - - for_each_cpu(cpu) { - if (info->size <= PAGE_SIZE) - kfree(info->entries[cpu]); - else - vfree(info->entries[cpu]); - } - kfree(info); -} -EXPORT_SYMBOL(xt_free_table_info); - -/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ -struct xt_table *xt_find_table_lock(int af, const char *name) -{ - struct xt_table *t; - - if (down_interruptible(&xt[af].mutex) != 0) - return ERR_PTR(-EINTR); - - list_for_each_entry(t, &xt[af].tables, list) - if (strcmp(t->name, name) == 0 && try_module_get(t->me)) - return t; - up(&xt[af].mutex); - return NULL; -} -EXPORT_SYMBOL_GPL(xt_find_table_lock); - -void xt_table_unlock(struct xt_table *table) -{ - up(&xt[table->af].mutex); -} -EXPORT_SYMBOL_GPL(xt_table_unlock); - - -struct xt_table_info * -xt_replace_table(struct xt_table *table, - unsigned int num_counters, - struct xt_table_info *newinfo, - int *error) -{ - struct xt_table_info *oldinfo, *private; - - /* Do the substitution. */ - write_lock_bh(&table->lock); - private = table->private; - /* Check inside lock: is the old number correct? */ - if (num_counters != private->number) { - duprintf("num_counters != table->private->number (%u/%u)\n", - num_counters, private->number); - write_unlock_bh(&table->lock); - *error = -EAGAIN; - return NULL; - } - oldinfo = private; - table->private = newinfo; - newinfo->initial_entries = oldinfo->initial_entries; - write_unlock_bh(&table->lock); - - return oldinfo; -} -EXPORT_SYMBOL_GPL(xt_replace_table); - -int xt_register_table(struct xt_table *table, - struct xt_table_info *bootstrap, - struct xt_table_info *newinfo) -{ - int ret; - struct xt_table_info *private; - - ret = down_interruptible(&xt[table->af].mutex); - if (ret != 0) - return ret; - - /* Don't autoload: we'd eat our tail... */ - if (list_named_find(&xt[table->af].tables, table->name)) { - ret = -EEXIST; - goto unlock; - } - - /* Simplifies replace_table code. */ - table->private = bootstrap; - if (!xt_replace_table(table, 0, newinfo, &ret)) - goto unlock; - - private = table->private; - duprintf("table->private->number = %u\n", private->number); - - /* save number of initial entries */ - private->initial_entries = private->number; - - rwlock_init(&table->lock); - list_prepend(&xt[table->af].tables, table); - - ret = 0; - unlock: - up(&xt[table->af].mutex); - return ret; -} -EXPORT_SYMBOL_GPL(xt_register_table); - -void *xt_unregister_table(struct xt_table *table) -{ - struct xt_table_info *private; - - down(&xt[table->af].mutex); - private = table->private; - LIST_DELETE(&xt[table->af].tables, table); - up(&xt[table->af].mutex); - - return private; -} -EXPORT_SYMBOL_GPL(xt_unregister_table); - -#ifdef CONFIG_PROC_FS -static char *xt_proto_prefix[NPROTO] = { - [AF_INET] = "ip", - [AF_INET6] = "ip6", - [NF_ARP] = "arp", -}; - -static struct list_head *xt_get_idx(struct list_head *list, struct seq_file *seq, loff_t pos) -{ - struct list_head *head = list->next; - - if (!head || list_empty(list)) - return NULL; - - while (pos && (head = head->next)) { - if (head == list) - return NULL; - pos--; - } - return pos ? NULL : head; -} - -static struct list_head *type2list(u_int16_t af, u_int16_t type) -{ - struct list_head *list; - - switch (type) { - case TARGET: - list = &xt[af].target; - break; - case MATCH: - list = &xt[af].match; - break; - case TABLE: - list = &xt[af].tables; - break; - default: - list = NULL; - break; - } - - return list; -} - -static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos) -{ - struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private; - u_int16_t af = (unsigned long)pde->data & 0xffff; - u_int16_t type = (unsigned long)pde->data >> 16; - struct list_head *list; - - if (af >= NPROTO) - return NULL; - - list = type2list(af, type); - if (!list) - return NULL; - - if (down_interruptible(&xt[af].mutex) != 0) - return NULL; - - return xt_get_idx(list, seq, *pos); -} - -static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos) -{ - struct proc_dir_entry *pde = seq->private; - u_int16_t af = (unsigned long)pde->data & 0xffff; - u_int16_t type = (unsigned long)pde->data >> 16; - struct list_head *list; - - if (af >= NPROTO) - return NULL; - - list = type2list(af, type); - if (!list) - return NULL; - - (*pos)++; - return xt_get_idx(list, seq, *pos); -} - -static void xt_tgt_seq_stop(struct seq_file *seq, void *v) -{ - struct proc_dir_entry *pde = seq->private; - u_int16_t af = (unsigned long)pde->data & 0xffff; - - up(&xt[af].mutex); -} - -static int xt_name_seq_show(struct seq_file *seq, void *v) -{ - char *name = (char *)v + sizeof(struct list_head); - - if (strlen(name)) - return seq_printf(seq, "%s\n", name); - else - return 0; -} - -static struct seq_operations xt_tgt_seq_ops = { - .start = xt_tgt_seq_start, - .next = xt_tgt_seq_next, - .stop = xt_tgt_seq_stop, - .show = xt_name_seq_show, -}; - -static int xt_tgt_open(struct inode *inode, struct file *file) -{ - int ret; - - ret = seq_open(file, &xt_tgt_seq_ops); - if (!ret) { - struct seq_file *seq = file->private_data; - struct proc_dir_entry *pde = PDE(inode); - - seq->private = pde; - } - - return ret; -} - -static struct file_operations xt_file_ops = { - .owner = THIS_MODULE, - .open = xt_tgt_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -#define FORMAT_TABLES "_tables_names" -#define FORMAT_MATCHES "_tables_matches" -#define FORMAT_TARGETS "_tables_targets" - -#endif /* CONFIG_PROC_FS */ - -int xt_proto_init(int af) -{ -#ifdef CONFIG_PROC_FS - char buf[XT_FUNCTION_MAXNAMELEN]; - struct proc_dir_entry *proc; -#endif - - if (af >= NPROTO) - return -EINVAL; - - -#ifdef CONFIG_PROC_FS - strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); - strlcat(buf, FORMAT_TABLES, sizeof(buf)); - proc = proc_net_fops_create(buf, 0440, &xt_file_ops); - if (!proc) - goto out; - proc->data = (void *) ((unsigned long) af | (TABLE << 16)); - - - strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); - strlcat(buf, FORMAT_MATCHES, sizeof(buf)); - proc = proc_net_fops_create(buf, 0440, &xt_file_ops); - if (!proc) - goto out_remove_tables; - proc->data = (void *) ((unsigned long) af | (MATCH << 16)); - - strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); - strlcat(buf, FORMAT_TARGETS, sizeof(buf)); - proc = proc_net_fops_create(buf, 0440, &xt_file_ops); - if (!proc) - goto out_remove_matches; - proc->data = (void *) ((unsigned long) af | (TARGET << 16)); -#endif - - return 0; - -#ifdef CONFIG_PROC_FS -out_remove_matches: - strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); - strlcat(buf, FORMAT_MATCHES, sizeof(buf)); - proc_net_remove(buf); - -out_remove_tables: - strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); - strlcat(buf, FORMAT_TABLES, sizeof(buf)); - proc_net_remove(buf); -out: - return -1; -#endif -} -EXPORT_SYMBOL_GPL(xt_proto_init); - -void xt_proto_fini(int af) -{ -#ifdef CONFIG_PROC_FS - char buf[XT_FUNCTION_MAXNAMELEN]; - - strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); - strlcat(buf, FORMAT_TABLES, sizeof(buf)); - proc_net_remove(buf); - - strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); - strlcat(buf, FORMAT_TARGETS, sizeof(buf)); - proc_net_remove(buf); - - strlcpy(buf, xt_proto_prefix[af], sizeof(buf)); - strlcat(buf, FORMAT_MATCHES, sizeof(buf)); - proc_net_remove(buf); -#endif /*CONFIG_PROC_FS*/ -} -EXPORT_SYMBOL_GPL(xt_proto_fini); - - -static int __init xt_init(void) -{ - int i; - - xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL); - if (!xt) - return -ENOMEM; - - for (i = 0; i < NPROTO; i++) { - init_MUTEX(&xt[i].mutex); - INIT_LIST_HEAD(&xt[i].target); - INIT_LIST_HEAD(&xt[i].match); - INIT_LIST_HEAD(&xt[i].tables); - } - return 0; -} - -static void __exit xt_fini(void) -{ - kfree(xt); -} - -module_init(xt_init); -module_exit(xt_fini); - diff --git a/trunk/net/netfilter/xt_NFQUEUE.c b/trunk/net/netfilter/xt_NFQUEUE.c deleted file mode 100644 index 8b76b6f8d1e4..000000000000 --- a/trunk/net/netfilter/xt_NFQUEUE.c +++ /dev/null @@ -1,107 +0,0 @@ -/* iptables module for using new netfilter netlink queue - * - * (C) 2005 by Harald Welte - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include - -#include -#include -#include -#include - -MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("[ip,ip6,arp]_tables NFQUEUE target"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("ipt_NFQUEUE"); -MODULE_ALIAS("ip6t_NFQUEUE"); -MODULE_ALIAS("arpt_NFQUEUE"); - -static unsigned int -target(struct sk_buff **pskb, - const struct net_device *in, - const struct net_device *out, - unsigned int hooknum, - const void *targinfo, - void *userinfo) -{ - const struct xt_NFQ_info *tinfo = targinfo; - - return NF_QUEUE_NR(tinfo->queuenum); -} - -static int -checkentry(const char *tablename, - const void *entry, - void *targinfo, - unsigned int targinfosize, - unsigned int hook_mask) -{ - if (targinfosize != XT_ALIGN(sizeof(struct xt_NFQ_info))) { - printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n", - targinfosize, - XT_ALIGN(sizeof(struct xt_NFQ_info))); - return 0; - } - - return 1; -} - -static struct xt_target ipt_NFQ_reg = { - .name = "NFQUEUE", - .target = target, - .checkentry = checkentry, - .me = THIS_MODULE, -}; - -static struct xt_target ip6t_NFQ_reg = { - .name = "NFQUEUE", - .target = target, - .checkentry = checkentry, - .me = THIS_MODULE, -}; - -static struct xt_target arpt_NFQ_reg = { - .name = "NFQUEUE", - .target = target, - .checkentry = checkentry, - .me = THIS_MODULE, -}; - -static int __init init(void) -{ - int ret; - ret = xt_register_target(AF_INET, &ipt_NFQ_reg); - if (ret) - return ret; - ret = xt_register_target(AF_INET6, &ip6t_NFQ_reg); - if (ret) - goto out_ip; - ret = xt_register_target(NF_ARP, &arpt_NFQ_reg); - if (ret) - goto out_ip6; - - return ret; -out_ip6: - xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); -out_ip: - xt_unregister_target(AF_INET, &ipt_NFQ_reg); - - return ret; -} - -static void __exit fini(void) -{ - xt_unregister_target(NF_ARP, &arpt_NFQ_reg); - xt_unregister_target(AF_INET6, &ip6t_NFQ_reg); - xt_unregister_target(AF_INET, &ipt_NFQ_reg); -} - -module_init(init); -module_exit(fini); diff --git a/trunk/net/netfilter/xt_length.c b/trunk/net/netfilter/xt_length.c deleted file mode 100644 index 39c8faea63de..000000000000 --- a/trunk/net/netfilter/xt_length.c +++ /dev/null @@ -1,99 +0,0 @@ -/* Kernel module to match packet length. */ -/* (C) 1999-2001 James Morris - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -#include -#include - -MODULE_AUTHOR("James Morris "); -MODULE_DESCRIPTION("IP tables packet length matching module"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("ipt_length"); -MODULE_ALIAS("ip6t_length"); - -static int -match(const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const void *matchinfo, - int offset, - unsigned int protoff, - int *hotdrop) -{ - const struct xt_length_info *info = matchinfo; - u_int16_t pktlen = ntohs(skb->nh.iph->tot_len); - - return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; -} - -static int -match6(const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const void *matchinfo, - int offset, - unsigned int protoff, - int *hotdrop) -{ - const struct xt_length_info *info = matchinfo; - u_int16_t pktlen = ntohs(skb->nh.ipv6h->payload_len) + sizeof(struct ipv6hdr); - - return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; -} - -static int -checkentry(const char *tablename, - const void *ip, - void *matchinfo, - unsigned int matchsize, - unsigned int hook_mask) -{ - if (matchsize != XT_ALIGN(sizeof(struct xt_length_info))) - return 0; - - return 1; -} - -static struct xt_match length_match = { - .name = "length", - .match = &match, - .checkentry = &checkentry, - .me = THIS_MODULE, -}; -static struct xt_match length6_match = { - .name = "length", - .match = &match6, - .checkentry = &checkentry, - .me = THIS_MODULE, -}; - -static int __init init(void) -{ - int ret; - ret = xt_register_match(AF_INET, &length_match); - if (ret) - return ret; - ret = xt_register_match(AF_INET6, &length6_match); - if (ret) - xt_unregister_match(AF_INET, &length_match); - - return ret; -} - -static void __exit fini(void) -{ - xt_unregister_match(AF_INET, &length_match); - xt_unregister_match(AF_INET6, &length6_match); -} - -module_init(init); -module_exit(fini); diff --git a/trunk/net/netfilter/xt_tcpudp.c b/trunk/net/netfilter/xt_tcpudp.c deleted file mode 100644 index 669c8113cc60..000000000000 --- a/trunk/net/netfilter/xt_tcpudp.c +++ /dev/null @@ -1,334 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("x_tables match for TCP and UDP, supports IPv4 and IPv6"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("xt_tcp"); -MODULE_ALIAS("xt_udp"); -MODULE_ALIAS("ipt_udp"); -MODULE_ALIAS("ipt_tcp"); -MODULE_ALIAS("ip6t_udp"); -MODULE_ALIAS("ip6t_tcp"); - -#ifdef DEBUG_IP_FIREWALL_USER -#define duprintf(format, args...) printk(format , ## args) -#else -#define duprintf(format, args...) -#endif - - -/* Returns 1 if the port is matched by the range, 0 otherwise */ -static inline int -port_match(u_int16_t min, u_int16_t max, u_int16_t port, int invert) -{ - int ret; - - ret = (port >= min && port <= max) ^ invert; - return ret; -} - -static int -tcp_find_option(u_int8_t option, - const struct sk_buff *skb, - unsigned int protoff, - unsigned int optlen, - int invert, - int *hotdrop) -{ - /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ - u_int8_t _opt[60 - sizeof(struct tcphdr)], *op; - unsigned int i; - - duprintf("tcp_match: finding option\n"); - - if (!optlen) - return invert; - - /* If we don't have the whole header, drop packet. */ - op = skb_header_pointer(skb, protoff + sizeof(struct tcphdr), - optlen, _opt); - if (op == NULL) { - *hotdrop = 1; - return 0; - } - - for (i = 0; i < optlen; ) { - if (op[i] == option) return !invert; - if (op[i] < 2) i++; - else i += op[i+1]?:1; - } - - return invert; -} - -static int -tcp_match(const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const void *matchinfo, - int offset, - unsigned int protoff, - int *hotdrop) -{ - struct tcphdr _tcph, *th; - const struct xt_tcp *tcpinfo = matchinfo; - - if (offset) { - /* To quote Alan: - - Don't allow a fragment of TCP 8 bytes in. Nobody normal - causes this. Its a cracker trying to break in by doing a - flag overwrite to pass the direction checks. - */ - if (offset == 1) { - duprintf("Dropping evil TCP offset=1 frag.\n"); - *hotdrop = 1; - } - /* Must not be a fragment. */ - return 0; - } - -#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) - - th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); - if (th == NULL) { - /* We've been asked to examine this packet, and we - can't. Hence, no choice but to drop. */ - duprintf("Dropping evil TCP offset=0 tinygram.\n"); - *hotdrop = 1; - return 0; - } - - if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1], - ntohs(th->source), - !!(tcpinfo->invflags & XT_TCP_INV_SRCPT))) - return 0; - if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1], - ntohs(th->dest), - !!(tcpinfo->invflags & XT_TCP_INV_DSTPT))) - return 0; - if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) - == tcpinfo->flg_cmp, - XT_TCP_INV_FLAGS)) - return 0; - if (tcpinfo->option) { - if (th->doff * 4 < sizeof(_tcph)) { - *hotdrop = 1; - return 0; - } - if (!tcp_find_option(tcpinfo->option, skb, protoff, - th->doff*4 - sizeof(_tcph), - tcpinfo->invflags & XT_TCP_INV_OPTION, - hotdrop)) - return 0; - } - return 1; -} - -/* Called when user tries to insert an entry of this type. */ -static int -tcp_checkentry(const char *tablename, - const void *info, - void *matchinfo, - unsigned int matchsize, - unsigned int hook_mask) -{ - const struct ipt_ip *ip = info; - const struct xt_tcp *tcpinfo = matchinfo; - - /* Must specify proto == TCP, and no unknown invflags */ - return ip->proto == IPPROTO_TCP - && !(ip->invflags & XT_INV_PROTO) - && matchsize == XT_ALIGN(sizeof(struct xt_tcp)) - && !(tcpinfo->invflags & ~XT_TCP_INV_MASK); -} - -/* Called when user tries to insert an entry of this type. */ -static int -tcp6_checkentry(const char *tablename, - const void *entry, - void *matchinfo, - unsigned int matchsize, - unsigned int hook_mask) -{ - const struct ip6t_ip6 *ipv6 = entry; - const struct xt_tcp *tcpinfo = matchinfo; - - /* Must specify proto == TCP, and no unknown invflags */ - return ipv6->proto == IPPROTO_TCP - && !(ipv6->invflags & XT_INV_PROTO) - && matchsize == XT_ALIGN(sizeof(struct xt_tcp)) - && !(tcpinfo->invflags & ~XT_TCP_INV_MASK); -} - - -static int -udp_match(const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const void *matchinfo, - int offset, - unsigned int protoff, - int *hotdrop) -{ - struct udphdr _udph, *uh; - const struct xt_udp *udpinfo = matchinfo; - - /* Must not be a fragment. */ - if (offset) - return 0; - - uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); - if (uh == NULL) { - /* We've been asked to examine this packet, and we - can't. Hence, no choice but to drop. */ - duprintf("Dropping evil UDP tinygram.\n"); - *hotdrop = 1; - return 0; - } - - return port_match(udpinfo->spts[0], udpinfo->spts[1], - ntohs(uh->source), - !!(udpinfo->invflags & XT_UDP_INV_SRCPT)) - && port_match(udpinfo->dpts[0], udpinfo->dpts[1], - ntohs(uh->dest), - !!(udpinfo->invflags & XT_UDP_INV_DSTPT)); -} - -/* Called when user tries to insert an entry of this type. */ -static int -udp_checkentry(const char *tablename, - const void *info, - void *matchinfo, - unsigned int matchinfosize, - unsigned int hook_mask) -{ - const struct ipt_ip *ip = info; - const struct xt_udp *udpinfo = matchinfo; - - /* Must specify proto == UDP, and no unknown invflags */ - if (ip->proto != IPPROTO_UDP || (ip->invflags & XT_INV_PROTO)) { - duprintf("ipt_udp: Protocol %u != %u\n", ip->proto, - IPPROTO_UDP); - return 0; - } - if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) { - duprintf("ipt_udp: matchsize %u != %u\n", - matchinfosize, XT_ALIGN(sizeof(struct xt_udp))); - return 0; - } - if (udpinfo->invflags & ~XT_UDP_INV_MASK) { - duprintf("ipt_udp: unknown flags %X\n", - udpinfo->invflags); - return 0; - } - - return 1; -} - -/* Called when user tries to insert an entry of this type. */ -static int -udp6_checkentry(const char *tablename, - const void *entry, - void *matchinfo, - unsigned int matchinfosize, - unsigned int hook_mask) -{ - const struct ip6t_ip6 *ipv6 = entry; - const struct xt_udp *udpinfo = matchinfo; - - /* Must specify proto == UDP, and no unknown invflags */ - if (ipv6->proto != IPPROTO_UDP || (ipv6->invflags & XT_INV_PROTO)) { - duprintf("ip6t_udp: Protocol %u != %u\n", ipv6->proto, - IPPROTO_UDP); - return 0; - } - if (matchinfosize != XT_ALIGN(sizeof(struct xt_udp))) { - duprintf("ip6t_udp: matchsize %u != %u\n", - matchinfosize, XT_ALIGN(sizeof(struct xt_udp))); - return 0; - } - if (udpinfo->invflags & ~XT_UDP_INV_MASK) { - duprintf("ip6t_udp: unknown flags %X\n", - udpinfo->invflags); - return 0; - } - - return 1; -} - -static struct xt_match tcp_matchstruct = { - .name = "tcp", - .match = &tcp_match, - .checkentry = &tcp_checkentry, - .me = THIS_MODULE, -}; -static struct xt_match tcp6_matchstruct = { - .name = "tcp", - .match = &tcp_match, - .checkentry = &tcp6_checkentry, - .me = THIS_MODULE, -}; - -static struct xt_match udp_matchstruct = { - .name = "udp", - .match = &udp_match, - .checkentry = &udp_checkentry, - .me = THIS_MODULE, -}; -static struct xt_match udp6_matchstruct = { - .name = "udp", - .match = &udp_match, - .checkentry = &udp6_checkentry, - .me = THIS_MODULE, -}; - -static int __init init(void) -{ - int ret; - ret = xt_register_match(AF_INET, &tcp_matchstruct); - if (ret) - return ret; - - ret = xt_register_match(AF_INET6, &tcp6_matchstruct); - if (ret) - goto out_unreg_tcp; - - ret = xt_register_match(AF_INET, &udp_matchstruct); - if (ret) - goto out_unreg_tcp6; - - ret = xt_register_match(AF_INET6, &udp6_matchstruct); - if (ret) - goto out_unreg_udp; - - return ret; - -out_unreg_udp: - xt_unregister_match(AF_INET, &tcp_matchstruct); -out_unreg_tcp6: - xt_unregister_match(AF_INET6, &tcp6_matchstruct); -out_unreg_tcp: - xt_unregister_match(AF_INET, &tcp_matchstruct); - return ret; -} - -static void __exit fini(void) -{ - xt_unregister_match(AF_INET6, &udp6_matchstruct); - xt_unregister_match(AF_INET, &udp_matchstruct); - xt_unregister_match(AF_INET6, &tcp6_matchstruct); - xt_unregister_match(AF_INET, &tcp_matchstruct); -} - -module_init(init); -module_exit(fini); diff --git a/trunk/net/netlink/genetlink.c b/trunk/net/netlink/genetlink.c index 4ae1538c54a9..3b1378498d50 100644 --- a/trunk/net/netlink/genetlink.c +++ b/trunk/net/netlink/genetlink.c @@ -222,6 +222,11 @@ int genl_register_family(struct genl_family *family) goto errout_locked; } + if (!try_module_get(family->owner)) { + err = -EBUSY; + goto errout_locked; + } + if (family->id == GENL_ID_GENERATE) { u16 newid = genl_generate_id(); @@ -278,6 +283,7 @@ int genl_unregister_family(struct genl_family *family) INIT_LIST_HEAD(&family->ops_list); genl_unlock(); + module_put(family->owner); kfree(family->attrbuf); genl_ctrl_event(CTRL_CMD_DELFAMILY, family); return 0; @@ -529,6 +535,7 @@ static struct genl_family genl_ctrl = { .name = "nlctrl", .version = 0x1, .maxattr = CTRL_ATTR_MAX, + .owner = THIS_MODULE, }; static int __init genl_init(void) diff --git a/trunk/net/sched/Kconfig b/trunk/net/sched/Kconfig index 778b1e5a4b50..8a260d43ceef 100644 --- a/trunk/net/sched/Kconfig +++ b/trunk/net/sched/Kconfig @@ -44,7 +44,7 @@ if NET_SCHED choice prompt "Packet scheduler clock source" - default NET_SCH_CLK_GETTIMEOFDAY + default NET_SCH_CLK_JIFFIES ---help--- Packet schedulers need a monotonic clock that increments at a static rate. The kernel provides several suitable interfaces, each with diff --git a/trunk/net/sched/act_ipt.c b/trunk/net/sched/act_ipt.c index 39a22a3ffe78..b5001939b74b 100644 --- a/trunk/net/sched/act_ipt.c +++ b/trunk/net/sched/act_ipt.c @@ -62,7 +62,7 @@ ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) struct ipt_target *target; int ret = 0; - target = xt_find_target(AF_INET, t->u.user.name, t->u.user.revision); + target = ipt_find_target(t->u.user.name, t->u.user.revision); if (!target) return -ENOENT; diff --git a/trunk/net/sctp/ipv6.c b/trunk/net/sctp/ipv6.c index 2e266129a764..04c7fab4edc4 100644 --- a/trunk/net/sctp/ipv6.c +++ b/trunk/net/sctp/ipv6.c @@ -180,7 +180,8 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport, } SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, " - "src:" NIP6_FMT " dst:" NIP6_FMT "\n", + "src:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x " + "dst:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", __FUNCTION__, skb, skb->len, NIP6(fl.fl6_src), NIP6(fl.fl6_dst)); @@ -205,13 +206,13 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, fl.oif = daddr->v6.sin6_scope_id; - SCTP_DEBUG_PRINTK("%s: DST=" NIP6_FMT " ", + SCTP_DEBUG_PRINTK("%s: DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", __FUNCTION__, NIP6(fl.fl6_dst)); if (saddr) { ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr); SCTP_DEBUG_PRINTK( - "SRC=" NIP6_FMT " - ", + "SRC=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x - ", NIP6(fl.fl6_src)); } @@ -220,7 +221,8 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc, struct rt6_info *rt; rt = (struct rt6_info *)dst; SCTP_DEBUG_PRINTK( - "rt6_dst:" NIP6_FMT " rt6_src:" NIP6_FMT "\n", + "rt6_dst:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x " + "rt6_src:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", NIP6(rt->rt6i_dst.addr), NIP6(rt->rt6i_src.addr)); } else { SCTP_DEBUG_PRINTK("NO ROUTE\n"); @@ -269,12 +271,13 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc, __u8 bmatchlen; SCTP_DEBUG_PRINTK("%s: asoc:%p dst:%p " - "daddr:" NIP6_FMT " ", + "daddr:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", __FUNCTION__, asoc, dst, NIP6(daddr->v6.sin6_addr)); if (!asoc) { ipv6_get_saddr(dst, &daddr->v6.sin6_addr,&saddr->v6.sin6_addr); - SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: " NIP6_FMT "\n", + SCTP_DEBUG_PRINTK("saddr from ipv6_get_saddr: " + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", NIP6(saddr->v6.sin6_addr)); return; } @@ -302,11 +305,13 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc, if (baddr) { memcpy(saddr, baddr, sizeof(union sctp_addr)); - SCTP_DEBUG_PRINTK("saddr: " NIP6_FMT "\n", + SCTP_DEBUG_PRINTK("saddr: " + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", NIP6(saddr->v6.sin6_addr)); } else { printk(KERN_ERR "%s: asoc:%p Could not find a valid source " - "address for the dest:" NIP6_FMT "\n", + "address for the " + "dest:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", __FUNCTION__, asoc, NIP6(daddr->v6.sin6_addr)); } @@ -670,7 +675,8 @@ static int sctp_v6_is_ce(const struct sk_buff *skb) /* Dump the v6 addr to the seq file. */ static void sctp_v6_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr) { - seq_printf(seq, NIP6_FMT " ", NIP6(addr->v6.sin6_addr)); + seq_printf(seq, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ", + NIP6(addr->v6.sin6_addr)); } /* Initialize a PF_INET6 socket msg_name. */ diff --git a/trunk/net/sctp/sm_statefuns.c b/trunk/net/sctp/sm_statefuns.c index 477d7f80dba6..557a7d90b92a 100644 --- a/trunk/net/sctp/sm_statefuns.c +++ b/trunk/net/sctp/sm_statefuns.c @@ -1036,14 +1036,14 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, if (from_addr.sa.sa_family == AF_INET6) { printk(KERN_WARNING "%s association %p could not find address " - NIP6_FMT "\n", + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", __FUNCTION__, asoc, NIP6(from_addr.v6.sin6_addr)); } else { printk(KERN_WARNING "%s association %p could not find address " - NIPQUAD_FMT "\n", + "%u.%u.%u.%u\n", __FUNCTION__, asoc, NIPQUAD(from_addr.v4.sin_addr.s_addr)); diff --git a/trunk/net/tipc/Kconfig b/trunk/net/tipc/Kconfig deleted file mode 100644 index 05ab18e62dee..000000000000 --- a/trunk/net/tipc/Kconfig +++ /dev/null @@ -1,112 +0,0 @@ -# -# TIPC configuration -# - -menu "TIPC Configuration (EXPERIMENTAL)" - depends on INET && EXPERIMENTAL - -config TIPC - tristate "The TIPC Protocol (EXPERIMENTAL)" - ---help--- - TBD. - - This protocol support is also available as a module ( = code which - can be inserted in and removed from the running kernel whenever you - want). The module will be called tipc. If you want to compile it - as a module, say M here and read . - - If in doubt, say N. - -config TIPC_ADVANCED - bool "TIPC: Advanced configuration" - depends on TIPC - default n - help - Saying Y here will open some advanced configuration - for TIPC. Most users do not need to bother, so if - unsure, just say N. - -config TIPC_ZONES - int "Maximum number of zones in network" - depends on TIPC && TIPC_ADVANCED - default "3" - help - Max number of zones inside TIPC network. Max supported value - is 255 zones, minimum is 1 - - Default is 3 zones in a network; setting this to higher - allows more zones but might use more memory. - -config TIPC_CLUSTERS - int "Maximum number of clusters in a zone" - depends on TIPC && TIPC_ADVANCED - default "1" - help - ***Only 1 (one cluster in a zone) is supported by current code. - Any value set here will be overridden.*** - - (Max number of clusters inside TIPC zone. Max supported - value is 4095 clusters, minimum is 1. - - Default is 1; setting this to smaller value might save - some memory, setting it to higher - allows more clusters and might consume more memory.) - -config TIPC_NODES - int "Maximum number of nodes in cluster" - depends on TIPC && TIPC_ADVANCED - default "255" - help - Maximum number of nodes inside a TIPC cluster. Maximum - supported value is 2047 nodes, minimum is 8. - - Setting this to a smaller value saves some memory, - setting it to higher allows more nodes. - -config TIPC_SLAVE_NODES - int "Maximum number of slave nodes in cluster" - depends on TIPC && TIPC_ADVANCED - default "0" - help - ***This capability is not supported by current code.*** - - Maximum number of slave nodes inside a TIPC cluster. Maximum - supported value is 2047 nodes, minimum is 0. - - Setting this to a smaller value saves some memory, - setting it to higher allows more nodes. - -config TIPC_PORTS - int "Maximum number of ports in a node" - depends on TIPC && TIPC_ADVANCED - default "8191" - help - Maximum number of ports within a node. Maximum - supported value is 64535 nodes, minimum is 127. - - Setting this to a smaller value saves some memory, - setting it to higher allows more ports. - -config TIPC_LOG - int "Size of log buffer" - depends on TIPC && TIPC_ADVANCED - default 0 - help - Size (in bytes) of TIPC's internal log buffer, which records the - occurrence of significant events. Maximum supported value - is 32768 bytes, minimum is 0. - - There is no need to enable the log buffer unless the node will be - managed remotely via TIPC. - -config TIPC_DEBUG - bool "Enable debugging support" - depends on TIPC - default n - help - This will enable debugging of TIPC. - - Only say Y here if you are having trouble with TIPC. It will - enable the display of detailed information about what is going on. - -endmenu diff --git a/trunk/net/tipc/Makefile b/trunk/net/tipc/Makefile deleted file mode 100644 index dceb7027946c..000000000000 --- a/trunk/net/tipc/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Makefile for the Linux TIPC layer -# - -obj-$(CONFIG_TIPC) := tipc.o - -tipc-y += addr.o bcast.o bearer.o config.o cluster.o \ - core.o handler.o link.o discover.o msg.o \ - name_distr.o subscr.o name_table.o net.o \ - netlink.o node.o node_subscr.o port.o ref.o \ - socket.o user_reg.o zone.o dbg.o eth_media.o - -# End of file diff --git a/trunk/net/tipc/addr.c b/trunk/net/tipc/addr.c deleted file mode 100644 index eca22260c98c..000000000000 --- a/trunk/net/tipc/addr.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * net/tipc/addr.c: TIPC address utility routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "dbg.h" -#include "addr.h" -#include "zone.h" -#include "cluster.h" -#include "net.h" - -u32 tipc_get_addr(void) -{ - return tipc_own_addr; -} - -/** - * addr_domain_valid - validates a network domain address - * - * Accepts , , , and <0.0.0>, - * where Z, C, and N are non-zero and do not exceed the configured limits. - * - * Returns 1 if domain address is valid, otherwise 0 - */ - -int addr_domain_valid(u32 addr) -{ - u32 n = tipc_node(addr); - u32 c = tipc_cluster(addr); - u32 z = tipc_zone(addr); - u32 max_nodes = tipc_max_nodes; - - if (is_slave(addr)) - max_nodes = LOWEST_SLAVE + tipc_max_slaves; - if (n > max_nodes) - return 0; - if (c > tipc_max_clusters) - return 0; - if (z > tipc_max_zones) - return 0; - - if (n && (!z || !c)) - return 0; - if (c && !z) - return 0; - return 1; -} - -/** - * addr_node_valid - validates a proposed network address for this node - * - * Accepts , where Z, C, and N are non-zero and do not exceed - * the configured limits. - * - * Returns 1 if address can be used, otherwise 0 - */ - -int addr_node_valid(u32 addr) -{ - return (addr_domain_valid(addr) && tipc_node(addr)); -} - diff --git a/trunk/net/tipc/addr.h b/trunk/net/tipc/addr.h deleted file mode 100644 index 02ca71783e2e..000000000000 --- a/trunk/net/tipc/addr.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * net/tipc/addr.h: Include file for TIPC address utility routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_ADDR_H -#define _TIPC_ADDR_H - -static inline u32 own_node(void) -{ - return tipc_node(tipc_own_addr); -} - -static inline u32 own_cluster(void) -{ - return tipc_cluster(tipc_own_addr); -} - -static inline u32 own_zone(void) -{ - return tipc_zone(tipc_own_addr); -} - -static inline int in_own_cluster(u32 addr) -{ - return !((addr ^ tipc_own_addr) >> 12); -} - -static inline int in_own_zone(u32 addr) -{ - return !((addr ^ tipc_own_addr) >> 24); -} - -static inline int is_slave(u32 addr) -{ - return addr & 0x800; -} - -static inline int may_route(u32 addr) -{ - return(addr ^ tipc_own_addr) >> 11; -} - -static inline int in_scope(u32 domain, u32 addr) -{ - if (!domain || (domain == addr)) - return 1; - if (domain == (addr & 0xfffff000u)) /* domain */ - return 1; - if (domain == (addr & 0xff000000u)) /* domain */ - return 1; - return 0; -} - -/** - * addr_scope - convert message lookup domain to equivalent 2-bit scope value - */ - -static inline int addr_scope(u32 domain) -{ - if (likely(!domain)) - return TIPC_ZONE_SCOPE; - if (tipc_node(domain)) - return TIPC_NODE_SCOPE; - if (tipc_cluster(domain)) - return TIPC_CLUSTER_SCOPE; - return TIPC_ZONE_SCOPE; -} - -/** - * addr_domain - convert 2-bit scope value to equivalent message lookup domain - * - * Needed when address of a named message must be looked up a second time - * after a network hop. - */ - -static inline int addr_domain(int sc) -{ - if (likely(sc == TIPC_NODE_SCOPE)) - return tipc_own_addr; - if (sc == TIPC_CLUSTER_SCOPE) - return tipc_addr(tipc_zone(tipc_own_addr), - tipc_cluster(tipc_own_addr), 0); - return tipc_addr(tipc_zone(tipc_own_addr), 0, 0); -} - -static inline char *addr_string_fill(char *string, u32 addr) -{ - snprintf(string, 16, "<%u.%u.%u>", - tipc_zone(addr), tipc_cluster(addr), tipc_node(addr)); - return string; -} - -int addr_domain_valid(u32); -int addr_node_valid(u32 addr); - -#endif diff --git a/trunk/net/tipc/bcast.c b/trunk/net/tipc/bcast.c deleted file mode 100644 index 9713d622efb8..000000000000 --- a/trunk/net/tipc/bcast.c +++ /dev/null @@ -1,806 +0,0 @@ -/* - * net/tipc/bcast.c: TIPC broadcast code - * - * Copyright (c) 2004-2006, Ericsson AB - * Copyright (c) 2004, Intel Corporation. - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "msg.h" -#include "dbg.h" -#include "link.h" -#include "net.h" -#include "node.h" -#include "port.h" -#include "addr.h" -#include "node_subscr.h" -#include "name_distr.h" -#include "bearer.h" -#include "name_table.h" -#include "bcast.h" - - -#define MAX_PKT_DEFAULT_MCAST 1500 /* bcast link max packet size (fixed) */ - -#define BCLINK_WIN_DEFAULT 20 /* bcast link window size (default) */ - -#define BCLINK_LOG_BUF_SIZE 0 - -/** - * struct bcbearer_pair - a pair of bearers used by broadcast link - * @primary: pointer to primary bearer - * @secondary: pointer to secondary bearer - * - * Bearers must have same priority and same set of reachable destinations - * to be paired. - */ - -struct bcbearer_pair { - struct bearer *primary; - struct bearer *secondary; -}; - -/** - * struct bcbearer - bearer used by broadcast link - * @bearer: (non-standard) broadcast bearer structure - * @media: (non-standard) broadcast media structure - * @bpairs: array of bearer pairs - * @bpairs_temp: array of bearer pairs used during creation of "bpairs" - */ - -struct bcbearer { - struct bearer bearer; - struct media media; - struct bcbearer_pair bpairs[MAX_BEARERS]; - struct bcbearer_pair bpairs_temp[TIPC_NUM_LINK_PRI]; -}; - -/** - * struct bclink - link used for broadcast messages - * @link: (non-standard) broadcast link structure - * @node: (non-standard) node structure representing b'cast link's peer node - * - * Handles sequence numbering, fragmentation, bundling, etc. - */ - -struct bclink { - struct link link; - struct node node; -}; - - -static struct bcbearer *bcbearer = NULL; -static struct bclink *bclink = NULL; -static struct link *bcl = NULL; -static spinlock_t bc_lock = SPIN_LOCK_UNLOCKED; - -char bc_link_name[] = "multicast-link"; - - -static inline u32 buf_seqno(struct sk_buff *buf) -{ - return msg_seqno(buf_msg(buf)); -} - -static inline u32 bcbuf_acks(struct sk_buff *buf) -{ - return (u32)(unsigned long)TIPC_SKB_CB(buf)->handle; -} - -static inline void bcbuf_set_acks(struct sk_buff *buf, u32 acks) -{ - TIPC_SKB_CB(buf)->handle = (void *)(unsigned long)acks; -} - -static inline void bcbuf_decr_acks(struct sk_buff *buf) -{ - bcbuf_set_acks(buf, bcbuf_acks(buf) - 1); -} - - -/** - * bclink_set_gap - set gap according to contents of current deferred pkt queue - * - * Called with 'node' locked, bc_lock unlocked - */ - -static inline void bclink_set_gap(struct node *n_ptr) -{ - struct sk_buff *buf = n_ptr->bclink.deferred_head; - - n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = - mod(n_ptr->bclink.last_in); - if (unlikely(buf != NULL)) - n_ptr->bclink.gap_to = mod(buf_seqno(buf) - 1); -} - -/** - * bclink_ack_allowed - test if ACK or NACK message can be sent at this moment - * - * This mechanism endeavours to prevent all nodes in network from trying - * to ACK or NACK at the same time. - * - * Note: TIPC uses a different trigger to distribute ACKs than it does to - * distribute NACKs, but tries to use the same spacing (divide by 16). - */ - -static inline int bclink_ack_allowed(u32 n) -{ - return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag); -} - - -/** - * bclink_retransmit_pkt - retransmit broadcast packets - * @after: sequence number of last packet to *not* retransmit - * @to: sequence number of last packet to retransmit - * - * Called with 'node' locked, bc_lock unlocked - */ - -static void bclink_retransmit_pkt(u32 after, u32 to) -{ - struct sk_buff *buf; - - spin_lock_bh(&bc_lock); - buf = bcl->first_out; - while (buf && less_eq(buf_seqno(buf), after)) { - buf = buf->next; - } - if (buf != NULL) - link_retransmit(bcl, buf, mod(to - after)); - spin_unlock_bh(&bc_lock); -} - -/** - * bclink_acknowledge - handle acknowledgement of broadcast packets - * @n_ptr: node that sent acknowledgement info - * @acked: broadcast sequence # that has been acknowledged - * - * Node is locked, bc_lock unlocked. - */ - -void bclink_acknowledge(struct node *n_ptr, u32 acked) -{ - struct sk_buff *crs; - struct sk_buff *next; - unsigned int released = 0; - - if (less_eq(acked, n_ptr->bclink.acked)) - return; - - spin_lock_bh(&bc_lock); - - /* Skip over packets that node has previously acknowledged */ - - crs = bcl->first_out; - while (crs && less_eq(buf_seqno(crs), n_ptr->bclink.acked)) { - crs = crs->next; - } - - /* Update packets that node is now acknowledging */ - - while (crs && less_eq(buf_seqno(crs), acked)) { - next = crs->next; - bcbuf_decr_acks(crs); - if (bcbuf_acks(crs) == 0) { - bcl->first_out = next; - bcl->out_queue_size--; - buf_discard(crs); - released = 1; - } - crs = next; - } - n_ptr->bclink.acked = acked; - - /* Try resolving broadcast link congestion, if necessary */ - - if (unlikely(bcl->next_out)) - link_push_queue(bcl); - if (unlikely(released && !list_empty(&bcl->waiting_ports))) - link_wakeup_ports(bcl, 0); - spin_unlock_bh(&bc_lock); -} - -/** - * bclink_send_ack - unicast an ACK msg - * - * net_lock and node lock set - */ - -static void bclink_send_ack(struct node *n_ptr) -{ - struct link *l_ptr = n_ptr->active_links[n_ptr->addr & 1]; - - if (l_ptr != NULL) - link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); -} - -/** - * bclink_send_nack- broadcast a NACK msg - * - * net_lock and node lock set - */ - -static void bclink_send_nack(struct node *n_ptr) -{ - struct sk_buff *buf; - struct tipc_msg *msg; - - if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to)) - return; - - buf = buf_acquire(INT_H_SIZE); - if (buf) { - msg = buf_msg(buf); - msg_init(msg, BCAST_PROTOCOL, STATE_MSG, - TIPC_OK, INT_H_SIZE, n_ptr->addr); - msg_set_mc_netid(msg, tipc_net_id); - msg_set_bcast_ack(msg, mod(n_ptr->bclink.last_in)); - msg_set_bcgap_after(msg, n_ptr->bclink.gap_after); - msg_set_bcgap_to(msg, n_ptr->bclink.gap_to); - msg_set_bcast_tag(msg, tipc_own_tag); - - if (bearer_send(&bcbearer->bearer, buf, 0)) { - bcl->stats.sent_nacks++; - buf_discard(buf); - } else { - bearer_schedule(bcl->b_ptr, bcl); - bcl->proto_msg_queue = buf; - bcl->stats.bearer_congs++; - } - - /* - * Ensure we doesn't send another NACK msg to the node - * until 16 more deferred messages arrive from it - * (i.e. helps prevent all nodes from NACK'ing at same time) - */ - - n_ptr->bclink.nack_sync = tipc_own_tag; - } -} - -/** - * bclink_check_gap - send a NACK if a sequence gap exists - * - * net_lock and node lock set - */ - -void bclink_check_gap(struct node *n_ptr, u32 last_sent) -{ - if (!n_ptr->bclink.supported || - less_eq(last_sent, mod(n_ptr->bclink.last_in))) - return; - - bclink_set_gap(n_ptr); - if (n_ptr->bclink.gap_after == n_ptr->bclink.gap_to) - n_ptr->bclink.gap_to = last_sent; - bclink_send_nack(n_ptr); -} - -/** - * bclink_peek_nack - process a NACK msg meant for another node - * - * Only net_lock set. - */ - -void bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to) -{ - struct node *n_ptr = node_find(dest); - u32 my_after, my_to; - - if (unlikely(!n_ptr || !node_is_up(n_ptr))) - return; - node_lock(n_ptr); - /* - * Modify gap to suppress unnecessary NACKs from this node - */ - my_after = n_ptr->bclink.gap_after; - my_to = n_ptr->bclink.gap_to; - - if (less_eq(gap_after, my_after)) { - if (less(my_after, gap_to) && less(gap_to, my_to)) - n_ptr->bclink.gap_after = gap_to; - else if (less_eq(my_to, gap_to)) - n_ptr->bclink.gap_to = n_ptr->bclink.gap_after; - } else if (less_eq(gap_after, my_to)) { - if (less_eq(my_to, gap_to)) - n_ptr->bclink.gap_to = gap_after; - } else { - /* - * Expand gap if missing bufs not in deferred queue: - */ - struct sk_buff *buf = n_ptr->bclink.deferred_head; - u32 prev = n_ptr->bclink.gap_to; - - for (; buf; buf = buf->next) { - u32 seqno = buf_seqno(buf); - - if (mod(seqno - prev) != 1) - buf = NULL; - if (seqno == gap_after) - break; - prev = seqno; - } - if (buf == NULL) - n_ptr->bclink.gap_to = gap_after; - } - /* - * Some nodes may send a complementary NACK now: - */ - if (bclink_ack_allowed(sender_tag + 1)) { - if (n_ptr->bclink.gap_to != n_ptr->bclink.gap_after) { - bclink_send_nack(n_ptr); - bclink_set_gap(n_ptr); - } - } - node_unlock(n_ptr); -} - -/** - * bclink_send_msg - broadcast a packet to all nodes in cluster - */ - -int bclink_send_msg(struct sk_buff *buf) -{ - int res; - - spin_lock_bh(&bc_lock); - - res = link_send_buf(bcl, buf); - if (unlikely(res == -ELINKCONG)) - buf_discard(buf); - else - bcl->stats.sent_info++; - - if (bcl->out_queue_size > bcl->stats.max_queue_sz) - bcl->stats.max_queue_sz = bcl->out_queue_size; - bcl->stats.queue_sz_counts++; - bcl->stats.accu_queue_sz += bcl->out_queue_size; - - spin_unlock_bh(&bc_lock); - return res; -} - -/** - * bclink_recv_pkt - receive a broadcast packet, and deliver upwards - * - * net_lock is read_locked, no other locks set - */ - -void bclink_recv_pkt(struct sk_buff *buf) -{ - struct tipc_msg *msg = buf_msg(buf); - struct node* node = node_find(msg_prevnode(msg)); - u32 next_in; - u32 seqno; - struct sk_buff *deferred; - - msg_dbg(msg, "bclink.supported || - (msg_mc_netid(msg) != tipc_net_id))) { - buf_discard(buf); - return; - } - - if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) { - msg_dbg(msg, "stats.recv_nacks++; - bclink_retransmit_pkt(msg_bcgap_after(msg), - msg_bcgap_to(msg)); - } else { - bclink_peek_nack(msg_destnode(msg), - msg_bcast_tag(msg), - msg_bcgap_after(msg), - msg_bcgap_to(msg)); - } - buf_discard(buf); - return; - } - - node_lock(node); -receive: - deferred = node->bclink.deferred_head; - next_in = mod(node->bclink.last_in + 1); - seqno = msg_seqno(msg); - - if (likely(seqno == next_in)) { - bcl->stats.recv_info++; - node->bclink.last_in++; - bclink_set_gap(node); - if (unlikely(bclink_ack_allowed(seqno))) { - bclink_send_ack(node); - bcl->stats.sent_acks++; - } - if (likely(msg_isdata(msg))) { - node_unlock(node); - port_recv_mcast(buf, NULL); - } else if (msg_user(msg) == MSG_BUNDLER) { - bcl->stats.recv_bundles++; - bcl->stats.recv_bundled += msg_msgcnt(msg); - node_unlock(node); - link_recv_bundle(buf); - } else if (msg_user(msg) == MSG_FRAGMENTER) { - bcl->stats.recv_fragments++; - if (link_recv_fragment(&node->bclink.defragm, - &buf, &msg)) - bcl->stats.recv_fragmented++; - node_unlock(node); - net_route_msg(buf); - } else { - node_unlock(node); - net_route_msg(buf); - } - if (deferred && (buf_seqno(deferred) == mod(next_in + 1))) { - node_lock(node); - buf = deferred; - msg = buf_msg(buf); - node->bclink.deferred_head = deferred->next; - goto receive; - } - return; - } else if (less(next_in, seqno)) { - u32 gap_after = node->bclink.gap_after; - u32 gap_to = node->bclink.gap_to; - - if (link_defer_pkt(&node->bclink.deferred_head, - &node->bclink.deferred_tail, - buf)) { - node->bclink.nack_sync++; - bcl->stats.deferred_recv++; - if (seqno == mod(gap_after + 1)) - node->bclink.gap_after = seqno; - else if (less(gap_after, seqno) && less(seqno, gap_to)) - node->bclink.gap_to = seqno; - } - if (bclink_ack_allowed(node->bclink.nack_sync)) { - if (gap_to != gap_after) - bclink_send_nack(node); - bclink_set_gap(node); - } - } else { - bcl->stats.duplicates++; - buf_discard(buf); - } - node_unlock(node); -} - -u32 bclink_get_last_sent(void) -{ - u32 last_sent = mod(bcl->next_out_no - 1); - - if (bcl->next_out) - last_sent = mod(buf_seqno(bcl->next_out) - 1); - return last_sent; -} - -u32 bclink_acks_missing(struct node *n_ptr) -{ - return (n_ptr->bclink.supported && - (bclink_get_last_sent() != n_ptr->bclink.acked)); -} - - -/** - * bcbearer_send - send a packet through the broadcast pseudo-bearer - * - * Send through as many bearers as necessary to reach all nodes - * that support TIPC multicasting. - * - * Returns 0 if packet sent successfully, non-zero if not - */ - -int bcbearer_send(struct sk_buff *buf, - struct tipc_bearer *unused1, - struct tipc_media_addr *unused2) -{ - static int send_count = 0; - - struct node_map remains; - struct node_map remains_new; - int bp_index; - int swap_time; - - /* Prepare buffer for broadcasting (if first time trying to send it) */ - - if (likely(!msg_non_seq(buf_msg(buf)))) { - struct tipc_msg *msg; - - assert(cluster_bcast_nodes.count != 0); - bcbuf_set_acks(buf, cluster_bcast_nodes.count); - msg = buf_msg(buf); - msg_set_non_seq(msg); - msg_set_mc_netid(msg, tipc_net_id); - } - - /* Determine if bearer pairs should be swapped following this attempt */ - - if ((swap_time = (++send_count >= 10))) - send_count = 0; - - /* Send buffer over bearers until all targets reached */ - - remains = cluster_bcast_nodes; - - for (bp_index = 0; bp_index < MAX_BEARERS; bp_index++) { - struct bearer *p = bcbearer->bpairs[bp_index].primary; - struct bearer *s = bcbearer->bpairs[bp_index].secondary; - - if (!p) - break; /* no more bearers to try */ - - nmap_diff(&remains, &p->nodes, &remains_new); - if (remains_new.count == remains.count) - continue; /* bearer pair doesn't add anything */ - - if (!p->publ.blocked && - !p->media->send_msg(buf, &p->publ, &p->media->bcast_addr)) { - if (swap_time && s && !s->publ.blocked) - goto swap; - else - goto update; - } - - if (!s || s->publ.blocked || - s->media->send_msg(buf, &s->publ, &s->media->bcast_addr)) - continue; /* unable to send using bearer pair */ -swap: - bcbearer->bpairs[bp_index].primary = s; - bcbearer->bpairs[bp_index].secondary = p; -update: - if (remains_new.count == 0) - return TIPC_OK; - - remains = remains_new; - } - - /* Unable to reach all targets */ - - bcbearer->bearer.publ.blocked = 1; - bcl->stats.bearer_congs++; - return ~TIPC_OK; -} - -/** - * bcbearer_sort - create sets of bearer pairs used by broadcast bearer - */ - -void bcbearer_sort(void) -{ - struct bcbearer_pair *bp_temp = bcbearer->bpairs_temp; - struct bcbearer_pair *bp_curr; - int b_index; - int pri; - - spin_lock_bh(&bc_lock); - - /* Group bearers by priority (can assume max of two per priority) */ - - memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp)); - - for (b_index = 0; b_index < MAX_BEARERS; b_index++) { - struct bearer *b = &bearers[b_index]; - - if (!b->active || !b->nodes.count) - continue; - - if (!bp_temp[b->priority].primary) - bp_temp[b->priority].primary = b; - else - bp_temp[b->priority].secondary = b; - } - - /* Create array of bearer pairs for broadcasting */ - - bp_curr = bcbearer->bpairs; - memset(bcbearer->bpairs, 0, sizeof(bcbearer->bpairs)); - - for (pri = (TIPC_NUM_LINK_PRI - 1); pri >= 0; pri--) { - - if (!bp_temp[pri].primary) - continue; - - bp_curr->primary = bp_temp[pri].primary; - - if (bp_temp[pri].secondary) { - if (nmap_equal(&bp_temp[pri].primary->nodes, - &bp_temp[pri].secondary->nodes)) { - bp_curr->secondary = bp_temp[pri].secondary; - } else { - bp_curr++; - bp_curr->primary = bp_temp[pri].secondary; - } - } - - bp_curr++; - } - - spin_unlock_bh(&bc_lock); -} - -/** - * bcbearer_push - resolve bearer congestion - * - * Forces bclink to push out any unsent packets, until all packets are gone - * or congestion reoccurs. - * No locks set when function called - */ - -void bcbearer_push(void) -{ - struct bearer *b_ptr; - - spin_lock_bh(&bc_lock); - b_ptr = &bcbearer->bearer; - if (b_ptr->publ.blocked) { - b_ptr->publ.blocked = 0; - bearer_lock_push(b_ptr); - } - spin_unlock_bh(&bc_lock); -} - - -int bclink_stats(char *buf, const u32 buf_size) -{ - struct print_buf pb; - - if (!bcl) - return 0; - - printbuf_init(&pb, buf, buf_size); - - spin_lock_bh(&bc_lock); - - tipc_printf(&pb, "Link <%s>\n" - " Window:%u packets\n", - bcl->name, bcl->queue_limit[0]); - tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", - bcl->stats.recv_info, - bcl->stats.recv_fragments, - bcl->stats.recv_fragmented, - bcl->stats.recv_bundles, - bcl->stats.recv_bundled); - tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", - bcl->stats.sent_info, - bcl->stats.sent_fragments, - bcl->stats.sent_fragmented, - bcl->stats.sent_bundles, - bcl->stats.sent_bundled); - tipc_printf(&pb, " RX naks:%u defs:%u dups:%u\n", - bcl->stats.recv_nacks, - bcl->stats.deferred_recv, - bcl->stats.duplicates); - tipc_printf(&pb, " TX naks:%u acks:%u dups:%u\n", - bcl->stats.sent_nacks, - bcl->stats.sent_acks, - bcl->stats.retransmitted); - tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", - bcl->stats.bearer_congs, - bcl->stats.link_congs, - bcl->stats.max_queue_sz, - bcl->stats.queue_sz_counts - ? (bcl->stats.accu_queue_sz / bcl->stats.queue_sz_counts) - : 0); - - spin_unlock_bh(&bc_lock); - return printbuf_validate(&pb); -} - -int bclink_reset_stats(void) -{ - if (!bcl) - return -ENOPROTOOPT; - - spin_lock_bh(&bc_lock); - memset(&bcl->stats, 0, sizeof(bcl->stats)); - spin_unlock_bh(&bc_lock); - return TIPC_OK; -} - -int bclink_set_queue_limits(u32 limit) -{ - if (!bcl) - return -ENOPROTOOPT; - if ((limit < TIPC_MIN_LINK_WIN) || (limit > TIPC_MAX_LINK_WIN)) - return -EINVAL; - - spin_lock_bh(&bc_lock); - link_set_queue_limits(bcl, limit); - spin_unlock_bh(&bc_lock); - return TIPC_OK; -} - -int bclink_init(void) -{ - bcbearer = kmalloc(sizeof(*bcbearer), GFP_ATOMIC); - bclink = kmalloc(sizeof(*bclink), GFP_ATOMIC); - if (!bcbearer || !bclink) { - nomem: - warn("Memory squeeze; Failed to create multicast link\n"); - kfree(bcbearer); - bcbearer = NULL; - kfree(bclink); - bclink = NULL; - return -ENOMEM; - } - - memset(bcbearer, 0, sizeof(struct bcbearer)); - INIT_LIST_HEAD(&bcbearer->bearer.cong_links); - bcbearer->bearer.media = &bcbearer->media; - bcbearer->media.send_msg = bcbearer_send; - sprintf(bcbearer->media.name, "tipc-multicast"); - - bcl = &bclink->link; - memset(bclink, 0, sizeof(struct bclink)); - INIT_LIST_HEAD(&bcl->waiting_ports); - bcl->next_out_no = 1; - bclink->node.lock = SPIN_LOCK_UNLOCKED; - bcl->owner = &bclink->node; - bcl->max_pkt = MAX_PKT_DEFAULT_MCAST; - link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); - bcl->b_ptr = &bcbearer->bearer; - bcl->state = WORKING_WORKING; - sprintf(bcl->name, bc_link_name); - - if (BCLINK_LOG_BUF_SIZE) { - char *pb = kmalloc(BCLINK_LOG_BUF_SIZE, GFP_ATOMIC); - - if (!pb) - goto nomem; - printbuf_init(&bcl->print_buf, pb, BCLINK_LOG_BUF_SIZE); - } - - return TIPC_OK; -} - -void bclink_stop(void) -{ - spin_lock_bh(&bc_lock); - if (bcbearer) { - link_stop(bcl); - if (BCLINK_LOG_BUF_SIZE) - kfree(bcl->print_buf.buf); - bcl = NULL; - kfree(bclink); - bclink = NULL; - kfree(bcbearer); - bcbearer = NULL; - } - spin_unlock_bh(&bc_lock); -} - diff --git a/trunk/net/tipc/bcast.h b/trunk/net/tipc/bcast.h deleted file mode 100644 index 5430e524b4f9..000000000000 --- a/trunk/net/tipc/bcast.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * net/tipc/bcast.h: Include file for TIPC broadcast code - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_BCAST_H -#define _TIPC_BCAST_H - -#define MAX_NODES 4096 -#define WSIZE 32 - -/** - * struct node_map - set of node identifiers - * @count: # of nodes in set - * @map: bitmap of node identifiers that are in the set - */ - -struct node_map { - u32 count; - u32 map[MAX_NODES / WSIZE]; -}; - - -#define PLSIZE 32 - -/** - * struct port_list - set of node local destination ports - * @count: # of ports in set (only valid for first entry in list) - * @next: pointer to next entry in list - * @ports: array of port references - */ - -struct port_list { - int count; - struct port_list *next; - u32 ports[PLSIZE]; -}; - - -struct node; - -extern char bc_link_name[]; - - -/** - * nmap_get - determine if node exists in a node map - */ - -static inline int nmap_get(struct node_map *nm_ptr, u32 node) -{ - int n = tipc_node(node); - int w = n / WSIZE; - int b = n % WSIZE; - - return nm_ptr->map[w] & (1 << b); -} - -/** - * nmap_add - add a node to a node map - */ - -static inline void nmap_add(struct node_map *nm_ptr, u32 node) -{ - int n = tipc_node(node); - int w = n / WSIZE; - u32 mask = (1 << (n % WSIZE)); - - if ((nm_ptr->map[w] & mask) == 0) { - nm_ptr->count++; - nm_ptr->map[w] |= mask; - } -} - -/** - * nmap_remove - remove a node from a node map - */ - -static inline void nmap_remove(struct node_map *nm_ptr, u32 node) -{ - int n = tipc_node(node); - int w = n / WSIZE; - u32 mask = (1 << (n % WSIZE)); - - if ((nm_ptr->map[w] & mask) != 0) { - nm_ptr->map[w] &= ~mask; - nm_ptr->count--; - } -} - -/** - * nmap_equal - test for equality of node maps - */ - -static inline int nmap_equal(struct node_map *nm_a, struct node_map *nm_b) -{ - return !memcmp(nm_a, nm_b, sizeof(*nm_a)); -} - -/** - * nmap_diff - find differences between node maps - * @nm_a: input node map A - * @nm_b: input node map B - * @nm_diff: output node map A-B (i.e. nodes of A that are not in B) - */ - -static inline void nmap_diff(struct node_map *nm_a, struct node_map *nm_b, - struct node_map *nm_diff) -{ - int stop = sizeof(nm_a->map) / sizeof(u32); - int w; - int b; - u32 map; - - memset(nm_diff, 0, sizeof(*nm_diff)); - for (w = 0; w < stop; w++) { - map = nm_a->map[w] ^ (nm_a->map[w] & nm_b->map[w]); - nm_diff->map[w] = map; - if (map != 0) { - for (b = 0 ; b < WSIZE; b++) { - if (map & (1 << b)) - nm_diff->count++; - } - } - } -} - -/** - * port_list_add - add a port to a port list, ensuring no duplicates - */ - -static inline void port_list_add(struct port_list *pl_ptr, u32 port) -{ - struct port_list *item = pl_ptr; - int i; - int item_sz = PLSIZE; - int cnt = pl_ptr->count; - - for (; ; cnt -= item_sz, item = item->next) { - if (cnt < PLSIZE) - item_sz = cnt; - for (i = 0; i < item_sz; i++) - if (item->ports[i] == port) - return; - if (i < PLSIZE) { - item->ports[i] = port; - pl_ptr->count++; - return; - } - if (!item->next) { - item->next = kmalloc(sizeof(*item), GFP_ATOMIC); - if (!item->next) { - warn("Memory squeeze: multicast destination port list is incomplete\n"); - return; - } - item->next->next = NULL; - } - } -} - -/** - * port_list_free - free dynamically created entries in port_list chain - * - * Note: First item is on stack, so it doesn't need to be released - */ - -static inline void port_list_free(struct port_list *pl_ptr) -{ - struct port_list *item; - struct port_list *next; - - for (item = pl_ptr->next; item; item = next) { - next = item->next; - kfree(item); - } -} - - -int bclink_init(void); -void bclink_stop(void); -void bclink_acknowledge(struct node *n_ptr, u32 acked); -int bclink_send_msg(struct sk_buff *buf); -void bclink_recv_pkt(struct sk_buff *buf); -u32 bclink_get_last_sent(void); -u32 bclink_acks_missing(struct node *n_ptr); -void bclink_check_gap(struct node *n_ptr, u32 seqno); -int bclink_stats(char *stats_buf, const u32 buf_size); -int bclink_reset_stats(void); -int bclink_set_queue_limits(u32 limit); -void bcbearer_sort(void); -void bcbearer_push(void); - -#endif diff --git a/trunk/net/tipc/bearer.c b/trunk/net/tipc/bearer.c deleted file mode 100644 index 3dd19fdc5a2c..000000000000 --- a/trunk/net/tipc/bearer.c +++ /dev/null @@ -1,692 +0,0 @@ -/* - * net/tipc/bearer.c: TIPC bearer code - * - * Copyright (c) 1996-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "config.h" -#include "dbg.h" -#include "bearer.h" -#include "link.h" -#include "port.h" -#include "discover.h" -#include "bcast.h" - -#define MAX_ADDR_STR 32 - -static struct media *media_list = 0; -static u32 media_count = 0; - -struct bearer *bearers = 0; - -/** - * media_name_valid - validate media name - * - * Returns 1 if media name is valid, otherwise 0. - */ - -static int media_name_valid(const char *name) -{ - u32 len; - - len = strlen(name); - if ((len + 1) > TIPC_MAX_MEDIA_NAME) - return 0; - return (strspn(name, tipc_alphabet) == len); -} - -/** - * media_find - locates specified media object by name - */ - -static struct media *media_find(const char *name) -{ - struct media *m_ptr; - u32 i; - - for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { - if (!strcmp(m_ptr->name, name)) - return m_ptr; - } - return 0; -} - -/** - * tipc_register_media - register a media type - * - * Bearers for this media type must be activated separately at a later stage. - */ - -int tipc_register_media(u32 media_type, - char *name, - int (*enable)(struct tipc_bearer *), - void (*disable)(struct tipc_bearer *), - int (*send_msg)(struct sk_buff *, - struct tipc_bearer *, - struct tipc_media_addr *), - char *(*addr2str)(struct tipc_media_addr *a, - char *str_buf, int str_size), - struct tipc_media_addr *bcast_addr, - const u32 bearer_priority, - const u32 link_tolerance, /* [ms] */ - const u32 send_window_limit) -{ - struct media *m_ptr; - u32 media_id; - u32 i; - int res = -EINVAL; - - write_lock_bh(&net_lock); - if (!media_list) - goto exit; - - if (!media_name_valid(name)) { - warn("Media registration error: illegal name <%s>\n", name); - goto exit; - } - if (!bcast_addr) { - warn("Media registration error: no broadcast address supplied\n"); - goto exit; - } - if (bearer_priority >= TIPC_NUM_LINK_PRI) { - warn("Media registration error: priority %u\n", bearer_priority); - goto exit; - } - if ((link_tolerance < TIPC_MIN_LINK_TOL) || - (link_tolerance > TIPC_MAX_LINK_TOL)) { - warn("Media registration error: tolerance %u\n", link_tolerance); - goto exit; - } - - media_id = media_count++; - if (media_id >= MAX_MEDIA) { - warn("Attempt to register more than %u media\n", MAX_MEDIA); - media_count--; - goto exit; - } - for (i = 0; i < media_id; i++) { - if (media_list[i].type_id == media_type) { - warn("Attempt to register second media with type %u\n", - media_type); - media_count--; - goto exit; - } - if (!strcmp(name, media_list[i].name)) { - warn("Attempt to re-register media name <%s>\n", name); - media_count--; - goto exit; - } - } - - m_ptr = &media_list[media_id]; - m_ptr->type_id = media_type; - m_ptr->send_msg = send_msg; - m_ptr->enable_bearer = enable; - m_ptr->disable_bearer = disable; - m_ptr->addr2str = addr2str; - memcpy(&m_ptr->bcast_addr, bcast_addr, sizeof(*bcast_addr)); - m_ptr->bcast = 1; - strcpy(m_ptr->name, name); - m_ptr->priority = bearer_priority; - m_ptr->tolerance = link_tolerance; - m_ptr->window = send_window_limit; - dbg("Media <%s> registered\n", name); - res = 0; -exit: - write_unlock_bh(&net_lock); - return res; -} - -/** - * media_addr_printf - record media address in print buffer - */ - -void media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a) -{ - struct media *m_ptr; - u32 media_type; - u32 i; - - media_type = ntohl(a->type); - for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { - if (m_ptr->type_id == media_type) - break; - } - - if ((i < media_count) && (m_ptr->addr2str != NULL)) { - char addr_str[MAX_ADDR_STR]; - - tipc_printf(pb, "%s(%s) ", m_ptr->name, - m_ptr->addr2str(a, addr_str, sizeof(addr_str))); - } else { - unchar *addr = (unchar *)&a->dev_addr; - - tipc_printf(pb, "UNKNOWN(%u):", media_type); - for (i = 0; i < (sizeof(*a) - sizeof(a->type)); i++) { - tipc_printf(pb, "%02x ", addr[i]); - } - } -} - -/** - * media_get_names - record names of registered media in buffer - */ - -struct sk_buff *media_get_names(void) -{ - struct sk_buff *buf; - struct media *m_ptr; - int i; - - buf = cfg_reply_alloc(MAX_MEDIA * TLV_SPACE(TIPC_MAX_MEDIA_NAME)); - if (!buf) - return NULL; - - read_lock_bh(&net_lock); - for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { - cfg_append_tlv(buf, TIPC_TLV_MEDIA_NAME, m_ptr->name, - strlen(m_ptr->name) + 1); - } - read_unlock_bh(&net_lock); - return buf; -} - -/** - * bearer_name_validate - validate & (optionally) deconstruct bearer name - * @name - ptr to bearer name string - * @name_parts - ptr to area for bearer name components (or NULL if not needed) - * - * Returns 1 if bearer name is valid, otherwise 0. - */ - -static int bearer_name_validate(const char *name, - struct bearer_name *name_parts) -{ - char name_copy[TIPC_MAX_BEARER_NAME]; - char *media_name; - char *if_name; - u32 media_len; - u32 if_len; - - /* copy bearer name & ensure length is OK */ - - name_copy[TIPC_MAX_BEARER_NAME - 1] = 0; - /* need above in case non-Posix strncpy() doesn't pad with nulls */ - strncpy(name_copy, name, TIPC_MAX_BEARER_NAME); - if (name_copy[TIPC_MAX_BEARER_NAME - 1] != 0) - return 0; - - /* ensure all component parts of bearer name are present */ - - media_name = name_copy; - if ((if_name = strchr(media_name, ':')) == NULL) - return 0; - *(if_name++) = 0; - media_len = if_name - media_name; - if_len = strlen(if_name) + 1; - - /* validate component parts of bearer name */ - - if ((media_len <= 1) || (media_len > TIPC_MAX_MEDIA_NAME) || - (if_len <= 1) || (if_len > TIPC_MAX_IF_NAME) || - (strspn(media_name, tipc_alphabet) != (media_len - 1)) || - (strspn(if_name, tipc_alphabet) != (if_len - 1))) - return 0; - - /* return bearer name components, if necessary */ - - if (name_parts) { - strcpy(name_parts->media_name, media_name); - strcpy(name_parts->if_name, if_name); - } - return 1; -} - -/** - * bearer_find - locates bearer object with matching bearer name - */ - -static struct bearer *bearer_find(const char *name) -{ - struct bearer *b_ptr; - u32 i; - - for (i = 0, b_ptr = bearers; i < MAX_BEARERS; i++, b_ptr++) { - if (b_ptr->active && (!strcmp(b_ptr->publ.name, name))) - return b_ptr; - } - return 0; -} - -/** - * bearer_find - locates bearer object with matching interface name - */ - -struct bearer *bearer_find_interface(const char *if_name) -{ - struct bearer *b_ptr; - char *b_if_name; - u32 i; - - for (i = 0, b_ptr = bearers; i < MAX_BEARERS; i++, b_ptr++) { - if (!b_ptr->active) - continue; - b_if_name = strchr(b_ptr->publ.name, ':') + 1; - if (!strcmp(b_if_name, if_name)) - return b_ptr; - } - return 0; -} - -/** - * bearer_get_names - record names of bearers in buffer - */ - -struct sk_buff *bearer_get_names(void) -{ - struct sk_buff *buf; - struct media *m_ptr; - struct bearer *b_ptr; - int i, j; - - buf = cfg_reply_alloc(MAX_BEARERS * TLV_SPACE(TIPC_MAX_BEARER_NAME)); - if (!buf) - return NULL; - - read_lock_bh(&net_lock); - for (i = 0, m_ptr = media_list; i < media_count; i++, m_ptr++) { - for (j = 0; j < MAX_BEARERS; j++) { - b_ptr = &bearers[j]; - if (b_ptr->active && (b_ptr->media == m_ptr)) { - cfg_append_tlv(buf, TIPC_TLV_BEARER_NAME, - b_ptr->publ.name, - strlen(b_ptr->publ.name) + 1); - } - } - } - read_unlock_bh(&net_lock); - return buf; -} - -void bearer_add_dest(struct bearer *b_ptr, u32 dest) -{ - nmap_add(&b_ptr->nodes, dest); - disc_update_link_req(b_ptr->link_req); - bcbearer_sort(); -} - -void bearer_remove_dest(struct bearer *b_ptr, u32 dest) -{ - nmap_remove(&b_ptr->nodes, dest); - disc_update_link_req(b_ptr->link_req); - bcbearer_sort(); -} - -/* - * bearer_push(): Resolve bearer congestion. Force the waiting - * links to push out their unsent packets, one packet per link - * per iteration, until all packets are gone or congestion reoccurs. - * 'net_lock' is read_locked when this function is called - * bearer.lock must be taken before calling - * Returns binary true(1) ore false(0) - */ -static int bearer_push(struct bearer *b_ptr) -{ - u32 res = TIPC_OK; - struct link *ln, *tln; - - if (b_ptr->publ.blocked) - return 0; - - while (!list_empty(&b_ptr->cong_links) && (res != PUSH_FAILED)) { - list_for_each_entry_safe(ln, tln, &b_ptr->cong_links, link_list) { - res = link_push_packet(ln); - if (res == PUSH_FAILED) - break; - if (res == PUSH_FINISHED) - list_move_tail(&ln->link_list, &b_ptr->links); - } - } - return list_empty(&b_ptr->cong_links); -} - -void bearer_lock_push(struct bearer *b_ptr) -{ - int res; - - spin_lock_bh(&b_ptr->publ.lock); - res = bearer_push(b_ptr); - spin_unlock_bh(&b_ptr->publ.lock); - if (res) - bcbearer_push(); -} - - -/* - * Interrupt enabling new requests after bearer congestion or blocking: - * See bearer_send(). - */ -void tipc_continue(struct tipc_bearer *tb_ptr) -{ - struct bearer *b_ptr = (struct bearer *)tb_ptr; - - spin_lock_bh(&b_ptr->publ.lock); - b_ptr->continue_count++; - if (!list_empty(&b_ptr->cong_links)) - k_signal((Handler)bearer_lock_push, (unsigned long)b_ptr); - b_ptr->publ.blocked = 0; - spin_unlock_bh(&b_ptr->publ.lock); -} - -/* - * Schedule link for sending of messages after the bearer - * has been deblocked by 'continue()'. This method is called - * when somebody tries to send a message via this link while - * the bearer is congested. 'net_lock' is in read_lock here - * bearer.lock is busy - */ - -static void bearer_schedule_unlocked(struct bearer *b_ptr, struct link *l_ptr) -{ - list_move_tail(&l_ptr->link_list, &b_ptr->cong_links); -} - -/* - * Schedule link for sending of messages after the bearer - * has been deblocked by 'continue()'. This method is called - * when somebody tries to send a message via this link while - * the bearer is congested. 'net_lock' is in read_lock here, - * bearer.lock is free - */ - -void bearer_schedule(struct bearer *b_ptr, struct link *l_ptr) -{ - spin_lock_bh(&b_ptr->publ.lock); - bearer_schedule_unlocked(b_ptr, l_ptr); - spin_unlock_bh(&b_ptr->publ.lock); -} - - -/* - * bearer_resolve_congestion(): Check if there is bearer congestion, - * and if there is, try to resolve it before returning. - * 'net_lock' is read_locked when this function is called - */ -int bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr) -{ - int res = 1; - - if (list_empty(&b_ptr->cong_links)) - return 1; - spin_lock_bh(&b_ptr->publ.lock); - if (!bearer_push(b_ptr)) { - bearer_schedule_unlocked(b_ptr, l_ptr); - res = 0; - } - spin_unlock_bh(&b_ptr->publ.lock); - return res; -} - - -/** - * tipc_enable_bearer - enable bearer with the given name - */ - -int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority) -{ - struct bearer *b_ptr; - struct media *m_ptr; - struct bearer_name b_name; - char addr_string[16]; - u32 bearer_id; - u32 with_this_prio; - u32 i; - int res = -EINVAL; - - if (tipc_mode != TIPC_NET_MODE) - return -ENOPROTOOPT; - if (!bearer_name_validate(name, &b_name) || - !addr_domain_valid(bcast_scope) || - !in_scope(bcast_scope, tipc_own_addr) || - (priority > TIPC_NUM_LINK_PRI)) - return -EINVAL; - - write_lock_bh(&net_lock); - if (!bearers) - goto failed; - - m_ptr = media_find(b_name.media_name); - if (!m_ptr) { - warn("No media <%s>\n", b_name.media_name); - goto failed; - } - if (priority == TIPC_NUM_LINK_PRI) - priority = m_ptr->priority; - -restart: - bearer_id = MAX_BEARERS; - with_this_prio = 1; - for (i = MAX_BEARERS; i-- != 0; ) { - if (!bearers[i].active) { - bearer_id = i; - continue; - } - if (!strcmp(name, bearers[i].publ.name)) { - warn("Bearer <%s> already enabled\n", name); - goto failed; - } - if ((bearers[i].priority == priority) && - (++with_this_prio > 2)) { - if (priority-- == 0) { - warn("Third bearer <%s> with priority %u, unable to lower to %u\n", - name, priority + 1, priority); - goto failed; - } - warn("Third bearer <%s> with priority %u, lowering to %u\n", - name, priority + 1, priority); - goto restart; - } - } - if (bearer_id >= MAX_BEARERS) { - warn("Attempt to enable more than %d bearers\n", MAX_BEARERS); - goto failed; - } - - b_ptr = &bearers[bearer_id]; - memset(b_ptr, 0, sizeof(struct bearer)); - - strcpy(b_ptr->publ.name, name); - res = m_ptr->enable_bearer(&b_ptr->publ); - if (res) { - warn("Failed to enable bearer <%s>\n", name); - goto failed; - } - - b_ptr->identity = bearer_id; - b_ptr->media = m_ptr; - b_ptr->net_plane = bearer_id + 'A'; - b_ptr->active = 1; - b_ptr->detect_scope = bcast_scope; - b_ptr->priority = priority; - INIT_LIST_HEAD(&b_ptr->cong_links); - INIT_LIST_HEAD(&b_ptr->links); - if (m_ptr->bcast) { - b_ptr->link_req = disc_init_link_req(b_ptr, &m_ptr->bcast_addr, - bcast_scope, 2); - } - b_ptr->publ.lock = SPIN_LOCK_UNLOCKED; - write_unlock_bh(&net_lock); - info("Enabled bearer <%s>, discovery domain %s\n", - name, addr_string_fill(addr_string, bcast_scope)); - return 0; -failed: - write_unlock_bh(&net_lock); - return res; -} - -/** - * tipc_block_bearer(): Block the bearer with the given name, - * and reset all its links - */ - -int tipc_block_bearer(const char *name) -{ - struct bearer *b_ptr = 0; - struct link *l_ptr; - struct link *temp_l_ptr; - - if (tipc_mode != TIPC_NET_MODE) - return -ENOPROTOOPT; - - read_lock_bh(&net_lock); - b_ptr = bearer_find(name); - if (!b_ptr) { - warn("Attempt to block unknown bearer <%s>\n", name); - read_unlock_bh(&net_lock); - return -EINVAL; - } - - spin_lock_bh(&b_ptr->publ.lock); - b_ptr->publ.blocked = 1; - list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { - struct node *n_ptr = l_ptr->owner; - - spin_lock_bh(&n_ptr->lock); - link_reset(l_ptr); - spin_unlock_bh(&n_ptr->lock); - } - spin_unlock_bh(&b_ptr->publ.lock); - read_unlock_bh(&net_lock); - info("Blocked bearer <%s>\n", name); - return TIPC_OK; -} - -/** - * bearer_disable - - * - * Note: This routine assumes caller holds net_lock. - */ - -static int bearer_disable(const char *name) -{ - struct bearer *b_ptr; - struct link *l_ptr; - struct link *temp_l_ptr; - - if (tipc_mode != TIPC_NET_MODE) - return -ENOPROTOOPT; - - b_ptr = bearer_find(name); - if (!b_ptr) { - warn("Attempt to disable unknown bearer <%s>\n", name); - return -EINVAL; - } - - disc_stop_link_req(b_ptr->link_req); - spin_lock_bh(&b_ptr->publ.lock); - b_ptr->link_req = NULL; - b_ptr->publ.blocked = 1; - if (b_ptr->media->disable_bearer) { - spin_unlock_bh(&b_ptr->publ.lock); - write_unlock_bh(&net_lock); - b_ptr->media->disable_bearer(&b_ptr->publ); - write_lock_bh(&net_lock); - spin_lock_bh(&b_ptr->publ.lock); - } - list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { - link_delete(l_ptr); - } - spin_unlock_bh(&b_ptr->publ.lock); - info("Disabled bearer <%s>\n", name); - memset(b_ptr, 0, sizeof(struct bearer)); - return TIPC_OK; -} - -int tipc_disable_bearer(const char *name) -{ - int res; - - write_lock_bh(&net_lock); - res = bearer_disable(name); - write_unlock_bh(&net_lock); - return res; -} - - - -int bearer_init(void) -{ - int res; - - write_lock_bh(&net_lock); - bearers = kmalloc(MAX_BEARERS * sizeof(struct bearer), GFP_ATOMIC); - media_list = kmalloc(MAX_MEDIA * sizeof(struct media), GFP_ATOMIC); - if (bearers && media_list) { - memset(bearers, 0, MAX_BEARERS * sizeof(struct bearer)); - memset(media_list, 0, MAX_MEDIA * sizeof(struct media)); - res = TIPC_OK; - } else { - kfree(bearers); - kfree(media_list); - bearers = 0; - media_list = 0; - res = -ENOMEM; - } - write_unlock_bh(&net_lock); - return res; -} - -void bearer_stop(void) -{ - u32 i; - - if (!bearers) - return; - - for (i = 0; i < MAX_BEARERS; i++) { - if (bearers[i].active) - bearers[i].publ.blocked = 1; - } - for (i = 0; i < MAX_BEARERS; i++) { - if (bearers[i].active) - bearer_disable(bearers[i].publ.name); - } - kfree(bearers); - kfree(media_list); - bearers = 0; - media_list = 0; - media_count = 0; -} - - diff --git a/trunk/net/tipc/bearer.h b/trunk/net/tipc/bearer.h deleted file mode 100644 index 21e63d3f0183..000000000000 --- a/trunk/net/tipc/bearer.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * net/tipc/bearer.h: Include file for TIPC bearer code - * - * Copyright (c) 1996-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_BEARER_H -#define _TIPC_BEARER_H - -#include -#include "bcast.h" - -#define MAX_BEARERS 8 -#define MAX_MEDIA 4 - - -/** - * struct media - TIPC media information available to internal users - * @send_msg: routine which handles buffer transmission - * @enable_bearer: routine which enables a bearer - * @disable_bearer: routine which disables a bearer - * @addr2str: routine which converts bearer's address to string form - * @bcast_addr: media address used in broadcasting - * @bcast: non-zero if media supports broadcasting [currently mandatory] - * @priority: default link (and bearer) priority - * @tolerance: default time (in ms) before declaring link failure - * @window: default window (in packets) before declaring link congestion - * @type_id: TIPC media identifier [defined in tipc_bearer.h] - * @name: media name - */ - -struct media { - int (*send_msg)(struct sk_buff *buf, - struct tipc_bearer *b_ptr, - struct tipc_media_addr *dest); - int (*enable_bearer)(struct tipc_bearer *b_ptr); - void (*disable_bearer)(struct tipc_bearer *b_ptr); - char *(*addr2str)(struct tipc_media_addr *a, - char *str_buf, int str_size); - struct tipc_media_addr bcast_addr; - int bcast; - u32 priority; - u32 tolerance; - u32 window; - u32 type_id; - char name[TIPC_MAX_MEDIA_NAME]; -}; - -/** - * struct bearer - TIPC bearer information available to internal users - * @publ: bearer information available to privileged users - * @media: ptr to media structure associated with bearer - * @priority: default link priority for bearer - * @detect_scope: network address mask used during automatic link creation - * @identity: array index of this bearer within TIPC bearer array - * @link_req: ptr to (optional) structure making periodic link setup requests - * @links: list of non-congested links associated with bearer - * @cong_links: list of congested links associated with bearer - * @continue_count: # of times bearer has resumed after congestion or blocking - * @active: non-zero if bearer structure is represents a bearer - * @net_plane: network plane ('A' through 'H') currently associated with bearer - * @nodes: indicates which nodes in cluster can be reached through bearer - */ - -struct bearer { - struct tipc_bearer publ; - struct media *media; - u32 priority; - u32 detect_scope; - u32 identity; - struct link_req *link_req; - struct list_head links; - struct list_head cong_links; - u32 continue_count; - int active; - char net_plane; - struct node_map nodes; -}; - -struct bearer_name { - char media_name[TIPC_MAX_MEDIA_NAME]; - char if_name[TIPC_MAX_IF_NAME]; -}; - -struct link; - -extern struct bearer *bearers; - -void media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a); -struct sk_buff *media_get_names(void); - -struct sk_buff *bearer_get_names(void); -void bearer_add_dest(struct bearer *b_ptr, u32 dest); -void bearer_remove_dest(struct bearer *b_ptr, u32 dest); -void bearer_schedule(struct bearer *b_ptr, struct link *l_ptr); -struct bearer *bearer_find_interface(const char *if_name); -int bearer_resolve_congestion(struct bearer *b_ptr, struct link *l_ptr); -int bearer_init(void); -void bearer_stop(void); -int bearer_broadcast(struct sk_buff *buf, struct tipc_bearer *b_ptr, - struct tipc_media_addr *dest); -void bearer_lock_push(struct bearer *b_ptr); - - -/** - * bearer_send- sends buffer to destination over bearer - * - * Returns true (1) if successful, or false (0) if unable to send - * - * IMPORTANT: - * The media send routine must not alter the buffer being passed in - * as it may be needed for later retransmission! - * - * If the media send routine returns a non-zero value (indicating that - * it was unable to send the buffer), it must: - * 1) mark the bearer as blocked, - * 2) call tipc_continue() once the bearer is able to send again. - * Media types that are unable to meet these two critera must ensure their - * send routine always returns success -- even if the buffer was not sent -- - * and let TIPC's link code deal with the undelivered message. - */ - -static inline int bearer_send(struct bearer *b_ptr, struct sk_buff *buf, - struct tipc_media_addr *dest) -{ - return !b_ptr->media->send_msg(buf, &b_ptr->publ, dest); -} - -/** - * bearer_congested - determines if bearer is currently congested - */ - -static inline int bearer_congested(struct bearer *b_ptr, struct link *l_ptr) -{ - if (unlikely(b_ptr->publ.blocked)) - return 1; - if (likely(list_empty(&b_ptr->cong_links))) - return 0; - return !bearer_resolve_congestion(b_ptr, l_ptr); -} - -#endif diff --git a/trunk/net/tipc/cluster.c b/trunk/net/tipc/cluster.c deleted file mode 100644 index f0f7bac51d41..000000000000 --- a/trunk/net/tipc/cluster.c +++ /dev/null @@ -1,576 +0,0 @@ -/* - * net/tipc/cluster.c: TIPC cluster management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "cluster.h" -#include "addr.h" -#include "node_subscr.h" -#include "link.h" -#include "node.h" -#include "net.h" -#include "msg.h" -#include "bearer.h" - -void cluster_multicast(struct cluster *c_ptr, struct sk_buff *buf, - u32 lower, u32 upper); -struct sk_buff *cluster_prepare_routing_msg(u32 data_size, u32 dest); - -struct node **local_nodes = 0; -struct node_map cluster_bcast_nodes = {0,{0,}}; -u32 highest_allowed_slave = 0; - -struct cluster *cluster_create(u32 addr) -{ - struct _zone *z_ptr; - struct cluster *c_ptr; - int max_nodes; - int alloc; - - c_ptr = (struct cluster *)kmalloc(sizeof(*c_ptr), GFP_ATOMIC); - if (c_ptr == NULL) - return 0; - memset(c_ptr, 0, sizeof(*c_ptr)); - - c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0); - if (in_own_cluster(addr)) - max_nodes = LOWEST_SLAVE + tipc_max_slaves; - else - max_nodes = tipc_max_nodes + 1; - alloc = sizeof(void *) * (max_nodes + 1); - c_ptr->nodes = (struct node **)kmalloc(alloc, GFP_ATOMIC); - if (c_ptr->nodes == NULL) { - kfree(c_ptr); - return 0; - } - memset(c_ptr->nodes, 0, alloc); - if (in_own_cluster(addr)) - local_nodes = c_ptr->nodes; - c_ptr->highest_slave = LOWEST_SLAVE - 1; - c_ptr->highest_node = 0; - - z_ptr = zone_find(tipc_zone(addr)); - if (z_ptr == NULL) { - z_ptr = zone_create(addr); - } - if (z_ptr != NULL) { - zone_attach_cluster(z_ptr, c_ptr); - c_ptr->owner = z_ptr; - } - else { - kfree(c_ptr); - c_ptr = 0; - } - - return c_ptr; -} - -void cluster_delete(struct cluster *c_ptr) -{ - u32 n_num; - - if (!c_ptr) - return; - for (n_num = 1; n_num <= c_ptr->highest_node; n_num++) { - node_delete(c_ptr->nodes[n_num]); - } - for (n_num = LOWEST_SLAVE; n_num <= c_ptr->highest_slave; n_num++) { - node_delete(c_ptr->nodes[n_num]); - } - kfree(c_ptr->nodes); - kfree(c_ptr); -} - -u32 cluster_next_node(struct cluster *c_ptr, u32 addr) -{ - struct node *n_ptr; - u32 n_num = tipc_node(addr) + 1; - - if (!c_ptr) - return addr; - for (; n_num <= c_ptr->highest_node; n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && node_has_active_links(n_ptr)) - return n_ptr->addr; - } - for (n_num = 1; n_num < tipc_node(addr); n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && node_has_active_links(n_ptr)) - return n_ptr->addr; - } - return 0; -} - -void cluster_attach_node(struct cluster *c_ptr, struct node *n_ptr) -{ - u32 n_num = tipc_node(n_ptr->addr); - u32 max_n_num = tipc_max_nodes; - - if (in_own_cluster(n_ptr->addr)) - max_n_num = highest_allowed_slave; - assert(n_num > 0); - assert(n_num <= max_n_num); - assert(c_ptr->nodes[n_num] == 0); - c_ptr->nodes[n_num] = n_ptr; - if (n_num > c_ptr->highest_node) - c_ptr->highest_node = n_num; -} - -/** - * cluster_select_router - select router to a cluster - * - * Uses deterministic and fair algorithm. - */ - -u32 cluster_select_router(struct cluster *c_ptr, u32 ref) -{ - u32 n_num; - u32 ulim = c_ptr->highest_node; - u32 mask; - u32 tstart; - - assert(!in_own_cluster(c_ptr->addr)); - if (!ulim) - return 0; - - /* Start entry must be random */ - mask = tipc_max_nodes; - while (mask > ulim) - mask >>= 1; - tstart = ref & mask; - n_num = tstart; - - /* Lookup upwards with wrap-around */ - do { - if (node_is_up(c_ptr->nodes[n_num])) - break; - } while (++n_num <= ulim); - if (n_num > ulim) { - n_num = 1; - do { - if (node_is_up(c_ptr->nodes[n_num])) - break; - } while (++n_num < tstart); - if (n_num == tstart) - return 0; - } - assert(n_num <= ulim); - return node_select_router(c_ptr->nodes[n_num], ref); -} - -/** - * cluster_select_node - select destination node within a remote cluster - * - * Uses deterministic and fair algorithm. - */ - -struct node *cluster_select_node(struct cluster *c_ptr, u32 selector) -{ - u32 n_num; - u32 mask = tipc_max_nodes; - u32 start_entry; - - assert(!in_own_cluster(c_ptr->addr)); - if (!c_ptr->highest_node) - return 0; - - /* Start entry must be random */ - while (mask > c_ptr->highest_node) { - mask >>= 1; - } - start_entry = (selector & mask) ? selector & mask : 1u; - assert(start_entry <= c_ptr->highest_node); - - /* Lookup upwards with wrap-around */ - for (n_num = start_entry; n_num <= c_ptr->highest_node; n_num++) { - if (node_has_active_links(c_ptr->nodes[n_num])) - return c_ptr->nodes[n_num]; - } - for (n_num = 1; n_num < start_entry; n_num++) { - if (node_has_active_links(c_ptr->nodes[n_num])) - return c_ptr->nodes[n_num]; - } - return 0; -} - -/* - * Routing table management: See description in node.c - */ - -struct sk_buff *cluster_prepare_routing_msg(u32 data_size, u32 dest) -{ - u32 size = INT_H_SIZE + data_size; - struct sk_buff *buf = buf_acquire(size); - struct tipc_msg *msg; - - if (buf) { - msg = buf_msg(buf); - memset((char *)msg, 0, size); - msg_init(msg, ROUTE_DISTRIBUTOR, 0, TIPC_OK, INT_H_SIZE, dest); - } - return buf; -} - -void cluster_bcast_new_route(struct cluster *c_ptr, u32 dest, - u32 lower, u32 upper) -{ - struct sk_buff *buf = cluster_prepare_routing_msg(0, c_ptr->addr); - struct tipc_msg *msg; - - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, dest); - msg_set_type(msg, ROUTE_ADDITION); - cluster_multicast(c_ptr, buf, lower, upper); - } else { - warn("Memory squeeze: broadcast of new route failed\n"); - } -} - -void cluster_bcast_lost_route(struct cluster *c_ptr, u32 dest, - u32 lower, u32 upper) -{ - struct sk_buff *buf = cluster_prepare_routing_msg(0, c_ptr->addr); - struct tipc_msg *msg; - - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, dest); - msg_set_type(msg, ROUTE_REMOVAL); - cluster_multicast(c_ptr, buf, lower, upper); - } else { - warn("Memory squeeze: broadcast of lost route failed\n"); - } -} - -void cluster_send_slave_routes(struct cluster *c_ptr, u32 dest) -{ - struct sk_buff *buf; - struct tipc_msg *msg; - u32 highest = c_ptr->highest_slave; - u32 n_num; - int send = 0; - - assert(!is_slave(dest)); - assert(in_own_cluster(dest)); - assert(in_own_cluster(c_ptr->addr)); - if (highest <= LOWEST_SLAVE) - return; - buf = cluster_prepare_routing_msg(highest - LOWEST_SLAVE + 1, - c_ptr->addr); - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, c_ptr->addr); - msg_set_type(msg, SLAVE_ROUTING_TABLE); - for (n_num = LOWEST_SLAVE; n_num <= highest; n_num++) { - if (c_ptr->nodes[n_num] && - node_has_active_links(c_ptr->nodes[n_num])) { - send = 1; - msg_set_dataoctet(msg, n_num); - } - } - if (send) - link_send(buf, dest, dest); - else - buf_discard(buf); - } else { - warn("Memory squeeze: broadcast of lost route failed\n"); - } -} - -void cluster_send_ext_routes(struct cluster *c_ptr, u32 dest) -{ - struct sk_buff *buf; - struct tipc_msg *msg; - u32 highest = c_ptr->highest_node; - u32 n_num; - int send = 0; - - if (in_own_cluster(c_ptr->addr)) - return; - assert(!is_slave(dest)); - assert(in_own_cluster(dest)); - highest = c_ptr->highest_node; - buf = cluster_prepare_routing_msg(highest + 1, c_ptr->addr); - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, c_ptr->addr); - msg_set_type(msg, EXT_ROUTING_TABLE); - for (n_num = 1; n_num <= highest; n_num++) { - if (c_ptr->nodes[n_num] && - node_has_active_links(c_ptr->nodes[n_num])) { - send = 1; - msg_set_dataoctet(msg, n_num); - } - } - if (send) - link_send(buf, dest, dest); - else - buf_discard(buf); - } else { - warn("Memory squeeze: broadcast of external route failed\n"); - } -} - -void cluster_send_local_routes(struct cluster *c_ptr, u32 dest) -{ - struct sk_buff *buf; - struct tipc_msg *msg; - u32 highest = c_ptr->highest_node; - u32 n_num; - int send = 0; - - assert(is_slave(dest)); - assert(in_own_cluster(c_ptr->addr)); - buf = cluster_prepare_routing_msg(highest, c_ptr->addr); - if (buf) { - msg = buf_msg(buf); - msg_set_remote_node(msg, c_ptr->addr); - msg_set_type(msg, LOCAL_ROUTING_TABLE); - for (n_num = 1; n_num <= highest; n_num++) { - if (c_ptr->nodes[n_num] && - node_has_active_links(c_ptr->nodes[n_num])) { - send = 1; - msg_set_dataoctet(msg, n_num); - } - } - if (send) - link_send(buf, dest, dest); - else - buf_discard(buf); - } else { - warn("Memory squeeze: broadcast of local route failed\n"); - } -} - -void cluster_recv_routing_table(struct sk_buff *buf) -{ - struct tipc_msg *msg = buf_msg(buf); - struct cluster *c_ptr; - struct node *n_ptr; - unchar *node_table; - u32 table_size; - u32 router; - u32 rem_node = msg_remote_node(msg); - u32 z_num; - u32 c_num; - u32 n_num; - - c_ptr = cluster_find(rem_node); - if (!c_ptr) { - c_ptr = cluster_create(rem_node); - if (!c_ptr) { - buf_discard(buf); - return; - } - } - - node_table = buf->data + msg_hdr_sz(msg); - table_size = msg_size(msg) - msg_hdr_sz(msg); - router = msg_prevnode(msg); - z_num = tipc_zone(rem_node); - c_num = tipc_cluster(rem_node); - - switch (msg_type(msg)) { - case LOCAL_ROUTING_TABLE: - assert(is_slave(tipc_own_addr)); - case EXT_ROUTING_TABLE: - for (n_num = 1; n_num < table_size; n_num++) { - if (node_table[n_num]) { - u32 addr = tipc_addr(z_num, c_num, n_num); - n_ptr = c_ptr->nodes[n_num]; - if (!n_ptr) { - n_ptr = node_create(addr); - } - if (n_ptr) - node_add_router(n_ptr, router); - } - } - break; - case SLAVE_ROUTING_TABLE: - assert(!is_slave(tipc_own_addr)); - assert(in_own_cluster(c_ptr->addr)); - for (n_num = 1; n_num < table_size; n_num++) { - if (node_table[n_num]) { - u32 slave_num = n_num + LOWEST_SLAVE; - u32 addr = tipc_addr(z_num, c_num, slave_num); - n_ptr = c_ptr->nodes[slave_num]; - if (!n_ptr) { - n_ptr = node_create(addr); - } - if (n_ptr) - node_add_router(n_ptr, router); - } - } - break; - case ROUTE_ADDITION: - if (!is_slave(tipc_own_addr)) { - assert(!in_own_cluster(c_ptr->addr) - || is_slave(rem_node)); - } else { - assert(in_own_cluster(c_ptr->addr) - && !is_slave(rem_node)); - } - n_ptr = c_ptr->nodes[tipc_node(rem_node)]; - if (!n_ptr) - n_ptr = node_create(rem_node); - if (n_ptr) - node_add_router(n_ptr, router); - break; - case ROUTE_REMOVAL: - if (!is_slave(tipc_own_addr)) { - assert(!in_own_cluster(c_ptr->addr) - || is_slave(rem_node)); - } else { - assert(in_own_cluster(c_ptr->addr) - && !is_slave(rem_node)); - } - n_ptr = c_ptr->nodes[tipc_node(rem_node)]; - if (n_ptr) - node_remove_router(n_ptr, router); - break; - default: - assert(!"Illegal routing manager message received\n"); - } - buf_discard(buf); -} - -void cluster_remove_as_router(struct cluster *c_ptr, u32 router) -{ - u32 start_entry; - u32 tstop; - u32 n_num; - - if (is_slave(router)) - return; /* Slave nodes can not be routers */ - - if (in_own_cluster(c_ptr->addr)) { - start_entry = LOWEST_SLAVE; - tstop = c_ptr->highest_slave; - } else { - start_entry = 1; - tstop = c_ptr->highest_node; - } - - for (n_num = start_entry; n_num <= tstop; n_num++) { - if (c_ptr->nodes[n_num]) { - node_remove_router(c_ptr->nodes[n_num], router); - } - } -} - -/** - * cluster_multicast - multicast message to local nodes - */ - -void cluster_multicast(struct cluster *c_ptr, struct sk_buff *buf, - u32 lower, u32 upper) -{ - struct sk_buff *buf_copy; - struct node *n_ptr; - u32 n_num; - u32 tstop; - - assert(lower <= upper); - assert(((lower >= 1) && (lower <= tipc_max_nodes)) || - ((lower >= LOWEST_SLAVE) && (lower <= highest_allowed_slave))); - assert(((upper >= 1) && (upper <= tipc_max_nodes)) || - ((upper >= LOWEST_SLAVE) && (upper <= highest_allowed_slave))); - assert(in_own_cluster(c_ptr->addr)); - - tstop = is_slave(upper) ? c_ptr->highest_slave : c_ptr->highest_node; - if (tstop > upper) - tstop = upper; - for (n_num = lower; n_num <= tstop; n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && node_has_active_links(n_ptr)) { - buf_copy = skb_copy(buf, GFP_ATOMIC); - if (buf_copy == NULL) - break; - msg_set_destnode(buf_msg(buf_copy), n_ptr->addr); - link_send(buf_copy, n_ptr->addr, n_ptr->addr); - } - } - buf_discard(buf); -} - -/** - * cluster_broadcast - broadcast message to all nodes within cluster - */ - -void cluster_broadcast(struct sk_buff *buf) -{ - struct sk_buff *buf_copy; - struct cluster *c_ptr; - struct node *n_ptr; - u32 n_num; - u32 tstart; - u32 tstop; - u32 node_type; - - if (tipc_mode == TIPC_NET_MODE) { - c_ptr = cluster_find(tipc_own_addr); - assert(in_own_cluster(c_ptr->addr)); /* For now */ - - /* Send to standard nodes, then repeat loop sending to slaves */ - tstart = 1; - tstop = c_ptr->highest_node; - for (node_type = 1; node_type <= 2; node_type++) { - for (n_num = tstart; n_num <= tstop; n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && node_has_active_links(n_ptr)) { - buf_copy = skb_copy(buf, GFP_ATOMIC); - if (buf_copy == NULL) - goto exit; - msg_set_destnode(buf_msg(buf_copy), - n_ptr->addr); - link_send(buf_copy, n_ptr->addr, - n_ptr->addr); - } - } - tstart = LOWEST_SLAVE; - tstop = c_ptr->highest_slave; - } - } -exit: - buf_discard(buf); -} - -int cluster_init(void) -{ - highest_allowed_slave = LOWEST_SLAVE + tipc_max_slaves; - return cluster_create(tipc_own_addr) ? TIPC_OK : -ENOMEM; -} - diff --git a/trunk/net/tipc/cluster.h b/trunk/net/tipc/cluster.h deleted file mode 100644 index 1ffb095991df..000000000000 --- a/trunk/net/tipc/cluster.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * net/tipc/cluster.h: Include file for TIPC cluster management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_CLUSTER_H -#define _TIPC_CLUSTER_H - -#include "addr.h" -#include "zone.h" - -#define LOWEST_SLAVE 2048u - -/** - * struct cluster - TIPC cluster structure - * @addr: network address of cluster - * @owner: pointer to zone that cluster belongs to - * @nodes: array of pointers to all nodes within cluster - * @highest_node: id of highest numbered node within cluster - * @highest_slave: (used for secondary node support) - */ - -struct cluster { - u32 addr; - struct _zone *owner; - struct node **nodes; - u32 highest_node; - u32 highest_slave; -}; - - -extern struct node **local_nodes; -extern u32 highest_allowed_slave; -extern struct node_map cluster_bcast_nodes; - -void cluster_remove_as_router(struct cluster *c_ptr, u32 router); -void cluster_send_ext_routes(struct cluster *c_ptr, u32 dest); -struct node *cluster_select_node(struct cluster *c_ptr, u32 selector); -u32 cluster_select_router(struct cluster *c_ptr, u32 ref); -void cluster_recv_routing_table(struct sk_buff *buf); -struct cluster *cluster_create(u32 addr); -void cluster_delete(struct cluster *c_ptr); -void cluster_attach_node(struct cluster *c_ptr, struct node *n_ptr); -void cluster_send_slave_routes(struct cluster *c_ptr, u32 dest); -void cluster_broadcast(struct sk_buff *buf); -int cluster_init(void); -u32 cluster_next_node(struct cluster *c_ptr, u32 addr); -void cluster_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); -void cluster_send_local_routes(struct cluster *c_ptr, u32 dest); -void cluster_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); - -static inline struct cluster *cluster_find(u32 addr) -{ - struct _zone *z_ptr = zone_find(addr); - - if (z_ptr) - return z_ptr->clusters[1]; - return 0; -} - -#endif diff --git a/trunk/net/tipc/config.c b/trunk/net/tipc/config.c deleted file mode 100644 index 8ddef4fce2c2..000000000000 --- a/trunk/net/tipc/config.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - * net/tipc/config.c: TIPC configuration management code - * - * Copyright (c) 2002-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "dbg.h" -#include "bearer.h" -#include "port.h" -#include "link.h" -#include "zone.h" -#include "addr.h" -#include "name_table.h" -#include "node.h" -#include "config.h" -#include "discover.h" - -struct subscr_data { - char usr_handle[8]; - u32 domain; - u32 port_ref; - struct list_head subd_list; -}; - -struct manager { - u32 user_ref; - u32 port_ref; - u32 subscr_ref; - u32 link_subscriptions; - struct list_head link_subscribers; -}; - -static struct manager mng = { 0}; - -static spinlock_t config_lock = SPIN_LOCK_UNLOCKED; - -static const void *req_tlv_area; /* request message TLV area */ -static int req_tlv_space; /* request message TLV area size */ -static int rep_headroom; /* reply message headroom to use */ - - -void cfg_link_event(u32 addr, char *name, int up) -{ - /* TIPC DOESN'T HANDLE LINK EVENT SUBSCRIPTIONS AT THE MOMENT */ -} - - -struct sk_buff *cfg_reply_alloc(int payload_size) -{ - struct sk_buff *buf; - - buf = alloc_skb(rep_headroom + payload_size, GFP_ATOMIC); - if (buf) - skb_reserve(buf, rep_headroom); - return buf; -} - -int cfg_append_tlv(struct sk_buff *buf, int tlv_type, - void *tlv_data, int tlv_data_size) -{ - struct tlv_desc *tlv = (struct tlv_desc *)buf->tail; - int new_tlv_space = TLV_SPACE(tlv_data_size); - - if (skb_tailroom(buf) < new_tlv_space) { - dbg("cfg_append_tlv unable to append TLV\n"); - return 0; - } - skb_put(buf, new_tlv_space); - tlv->tlv_type = htons(tlv_type); - tlv->tlv_len = htons(TLV_LENGTH(tlv_data_size)); - if (tlv_data_size && tlv_data) - memcpy(TLV_DATA(tlv), tlv_data, tlv_data_size); - return 1; -} - -struct sk_buff *cfg_reply_unsigned_type(u16 tlv_type, u32 value) -{ - struct sk_buff *buf; - u32 value_net; - - buf = cfg_reply_alloc(TLV_SPACE(sizeof(value))); - if (buf) { - value_net = htonl(value); - cfg_append_tlv(buf, tlv_type, &value_net, - sizeof(value_net)); - } - return buf; -} - -struct sk_buff *cfg_reply_string_type(u16 tlv_type, char *string) -{ - struct sk_buff *buf; - int string_len = strlen(string) + 1; - - buf = cfg_reply_alloc(TLV_SPACE(string_len)); - if (buf) - cfg_append_tlv(buf, tlv_type, string, string_len); - return buf; -} - - - - -#if 0 - -/* Now obsolete code for handling commands not yet implemented the new way */ - -int tipc_cfg_cmd(const struct tipc_cmd_msg * msg, - char *data, - u32 sz, - u32 *ret_size, - struct tipc_portid *orig) -{ - int rv = -EINVAL; - u32 cmd = msg->cmd; - - *ret_size = 0; - switch (cmd) { - case TIPC_REMOVE_LINK: - case TIPC_CMD_BLOCK_LINK: - case TIPC_CMD_UNBLOCK_LINK: - if (!cfg_check_connection(orig)) - rv = link_control(msg->argv.link_name, msg->cmd, 0); - break; - case TIPC_ESTABLISH: - { - int connected; - - tipc_isconnected(mng.conn_port_ref, &connected); - if (connected || !orig) { - rv = TIPC_FAILURE; - break; - } - rv = tipc_connect2port(mng.conn_port_ref, orig); - if (rv == TIPC_OK) - orig = 0; - break; - } - case TIPC_GET_PEER_ADDRESS: - *ret_size = link_peer_addr(msg->argv.link_name, data, sz); - break; - case TIPC_GET_ROUTES: - rv = TIPC_OK; - break; - default: {} - } - if (*ret_size) - rv = TIPC_OK; - return rv; -} - -static void cfg_cmd_event(struct tipc_cmd_msg *msg, - char *data, - u32 sz, - struct tipc_portid const *orig) -{ - int rv = -EINVAL; - struct tipc_cmd_result_msg rmsg; - struct iovec msg_sect[2]; - int *arg; - - msg->cmd = ntohl(msg->cmd); - - cfg_prepare_res_msg(msg->cmd, msg->usr_handle, rv, &rmsg, msg_sect, - data, 0); - if (ntohl(msg->magic) != TIPC_MAGIC) - goto exit; - - switch (msg->cmd) { - case TIPC_CREATE_LINK: - if (!cfg_check_connection(orig)) - rv = disc_create_link(&msg->argv.create_link); - break; - case TIPC_LINK_SUBSCRIBE: - { - struct subscr_data *sub; - - if (mng.link_subscriptions > 64) - break; - sub = (struct subscr_data *)kmalloc(sizeof(*sub), - GFP_ATOMIC); - if (sub == NULL) { - warn("Memory squeeze; dropped remote link subscription\n"); - break; - } - INIT_LIST_HEAD(&sub->subd_list); - tipc_createport(mng.user_ref, - (void *)sub, - TIPC_HIGH_IMPORTANCE, - 0, - 0, - (tipc_conn_shutdown_event)cfg_linksubscr_cancel, - 0, - 0, - (tipc_conn_msg_event)cfg_linksubscr_cancel, - 0, - &sub->port_ref); - if (!sub->port_ref) { - kfree(sub); - break; - } - memcpy(sub->usr_handle,msg->usr_handle, - sizeof(sub->usr_handle)); - sub->domain = msg->argv.domain; - list_add_tail(&sub->subd_list, &mng.link_subscribers); - tipc_connect2port(sub->port_ref, orig); - rmsg.retval = TIPC_OK; - tipc_send(sub->port_ref, 2u, msg_sect); - mng.link_subscriptions++; - return; - } - default: - rv = tipc_cfg_cmd(msg, data, sz, (u32 *)&msg_sect[1].iov_len, orig); - } - exit: - rmsg.result_len = htonl(msg_sect[1].iov_len); - rmsg.retval = htonl(rv); - cfg_respond(msg_sect, 2u, orig); -} -#endif - -static struct sk_buff *cfg_enable_bearer(void) -{ - struct tipc_bearer_config *args; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_CONFIG)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - args = (struct tipc_bearer_config *)TLV_DATA(req_tlv_area); - if (tipc_enable_bearer(args->name, - ntohl(args->detect_scope), - ntohl(args->priority))) - return cfg_reply_error_string("unable to enable bearer"); - - return cfg_reply_none(); -} - -static struct sk_buff *cfg_disable_bearer(void) -{ - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_BEARER_NAME)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - if (tipc_disable_bearer((char *)TLV_DATA(req_tlv_area))) - return cfg_reply_error_string("unable to disable bearer"); - - return cfg_reply_none(); -} - -static struct sk_buff *cfg_set_own_addr(void) -{ - u32 addr; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - addr = *(u32 *)TLV_DATA(req_tlv_area); - addr = ntohl(addr); - if (addr == tipc_own_addr) - return cfg_reply_none(); - if (!addr_node_valid(addr)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (node address)"); - if (tipc_own_addr) - return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change node address once assigned)"); - - spin_unlock_bh(&config_lock); - stop_net(); - tipc_own_addr = addr; - start_net(); - spin_lock_bh(&config_lock); - return cfg_reply_none(); -} - -static struct sk_buff *cfg_set_remote_mng(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - tipc_remote_management = (value != 0); - return cfg_reply_none(); -} - -static struct sk_buff *cfg_set_max_publications(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - if (value != delimit(value, 1, 65535)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (max publications must be 1-65535)"); - tipc_max_publications = value; - return cfg_reply_none(); -} - -static struct sk_buff *cfg_set_max_subscriptions(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - if (value != delimit(value, 1, 65535)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (max subscriptions must be 1-65535"); - tipc_max_subscriptions = value; - return cfg_reply_none(); -} - -static struct sk_buff *cfg_set_max_ports(void) -{ - int orig_mode; - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - if (value != delimit(value, 127, 65535)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (max ports must be 127-65535)"); - - if (value == tipc_max_ports) - return cfg_reply_none(); - - if (atomic_read(&tipc_user_count) > 2) - return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change max ports while TIPC users exist)"); - - spin_unlock_bh(&config_lock); - orig_mode = tipc_get_mode(); - if (orig_mode == TIPC_NET_MODE) - stop_net(); - stop_core(); - tipc_max_ports = value; - start_core(); - if (orig_mode == TIPC_NET_MODE) - start_net(); - spin_lock_bh(&config_lock); - return cfg_reply_none(); -} - -static struct sk_buff *set_net_max(int value, int *parameter) -{ - int orig_mode; - - if (value != *parameter) { - orig_mode = tipc_get_mode(); - if (orig_mode == TIPC_NET_MODE) - stop_net(); - *parameter = value; - if (orig_mode == TIPC_NET_MODE) - start_net(); - } - - return cfg_reply_none(); -} - -static struct sk_buff *cfg_set_max_zones(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - if (value != delimit(value, 1, 255)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (max zones must be 1-255)"); - return set_net_max(value, &tipc_max_zones); -} - -static struct sk_buff *cfg_set_max_clusters(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - if (value != 1) - return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (max clusters fixed at 1)"); - return cfg_reply_none(); -} - -static struct sk_buff *cfg_set_max_nodes(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - if (value != delimit(value, 8, 2047)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (max nodes must be 8-2047)"); - return set_net_max(value, &tipc_max_nodes); -} - -static struct sk_buff *cfg_set_max_slaves(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - if (value != 0) - return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (max secondary nodes fixed at 0)"); - return cfg_reply_none(); -} - -static struct sk_buff *cfg_set_netid(void) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - if (value != delimit(value, 1, 9999)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (network id must be 1-9999)"); - - if (tipc_own_addr) - return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change network id once part of network)"); - - return set_net_max(value, &tipc_net_id); -} - -struct sk_buff *cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area, - int request_space, int reply_headroom) -{ - struct sk_buff *rep_tlv_buf; - - spin_lock_bh(&config_lock); - - /* Save request and reply details in a well-known location */ - - req_tlv_area = request_area; - req_tlv_space = request_space; - rep_headroom = reply_headroom; - - /* Check command authorization */ - - if (likely(orig_node == tipc_own_addr)) { - /* command is permitted */ - } else if (cmd >= 0x8000) { - rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot be done remotely)"); - goto exit; - } else if (!tipc_remote_management) { - rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NO_REMOTE); - goto exit; - } - else if (cmd >= 0x4000) { - u32 domain = 0; - - if ((nametbl_translate(TIPC_ZM_SRV, 0, &domain) == 0) || - (domain != orig_node)) { - rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NOT_ZONE_MSTR); - goto exit; - } - } - - /* Call appropriate processing routine */ - - switch (cmd) { - case TIPC_CMD_NOOP: - rep_tlv_buf = cfg_reply_none(); - break; - case TIPC_CMD_GET_NODES: - rep_tlv_buf = node_get_nodes(req_tlv_area, req_tlv_space); - break; - case TIPC_CMD_GET_LINKS: - rep_tlv_buf = node_get_links(req_tlv_area, req_tlv_space); - break; - case TIPC_CMD_SHOW_LINK_STATS: - rep_tlv_buf = link_cmd_show_stats(req_tlv_area, req_tlv_space); - break; - case TIPC_CMD_RESET_LINK_STATS: - rep_tlv_buf = link_cmd_reset_stats(req_tlv_area, req_tlv_space); - break; - case TIPC_CMD_SHOW_NAME_TABLE: - rep_tlv_buf = nametbl_get(req_tlv_area, req_tlv_space); - break; - case TIPC_CMD_GET_BEARER_NAMES: - rep_tlv_buf = bearer_get_names(); - break; - case TIPC_CMD_GET_MEDIA_NAMES: - rep_tlv_buf = media_get_names(); - break; - case TIPC_CMD_SHOW_PORTS: - rep_tlv_buf = port_get_ports(); - break; -#if 0 - case TIPC_CMD_SHOW_PORT_STATS: - rep_tlv_buf = port_show_stats(req_tlv_area, req_tlv_space); - break; - case TIPC_CMD_RESET_PORT_STATS: - rep_tlv_buf = cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED); - break; -#endif - case TIPC_CMD_SET_LOG_SIZE: - rep_tlv_buf = log_resize(req_tlv_area, req_tlv_space); - break; - case TIPC_CMD_DUMP_LOG: - rep_tlv_buf = log_dump(); - break; - case TIPC_CMD_SET_LINK_TOL: - case TIPC_CMD_SET_LINK_PRI: - case TIPC_CMD_SET_LINK_WINDOW: - rep_tlv_buf = link_cmd_config(req_tlv_area, req_tlv_space, cmd); - break; - case TIPC_CMD_ENABLE_BEARER: - rep_tlv_buf = cfg_enable_bearer(); - break; - case TIPC_CMD_DISABLE_BEARER: - rep_tlv_buf = cfg_disable_bearer(); - break; - case TIPC_CMD_SET_NODE_ADDR: - rep_tlv_buf = cfg_set_own_addr(); - break; - case TIPC_CMD_SET_REMOTE_MNG: - rep_tlv_buf = cfg_set_remote_mng(); - break; - case TIPC_CMD_SET_MAX_PORTS: - rep_tlv_buf = cfg_set_max_ports(); - break; - case TIPC_CMD_SET_MAX_PUBL: - rep_tlv_buf = cfg_set_max_publications(); - break; - case TIPC_CMD_SET_MAX_SUBSCR: - rep_tlv_buf = cfg_set_max_subscriptions(); - break; - case TIPC_CMD_SET_MAX_ZONES: - rep_tlv_buf = cfg_set_max_zones(); - break; - case TIPC_CMD_SET_MAX_CLUSTERS: - rep_tlv_buf = cfg_set_max_clusters(); - break; - case TIPC_CMD_SET_MAX_NODES: - rep_tlv_buf = cfg_set_max_nodes(); - break; - case TIPC_CMD_SET_MAX_SLAVES: - rep_tlv_buf = cfg_set_max_slaves(); - break; - case TIPC_CMD_SET_NETID: - rep_tlv_buf = cfg_set_netid(); - break; - case TIPC_CMD_GET_REMOTE_MNG: - rep_tlv_buf = cfg_reply_unsigned(tipc_remote_management); - break; - case TIPC_CMD_GET_MAX_PORTS: - rep_tlv_buf = cfg_reply_unsigned(tipc_max_ports); - break; - case TIPC_CMD_GET_MAX_PUBL: - rep_tlv_buf = cfg_reply_unsigned(tipc_max_publications); - break; - case TIPC_CMD_GET_MAX_SUBSCR: - rep_tlv_buf = cfg_reply_unsigned(tipc_max_subscriptions); - break; - case TIPC_CMD_GET_MAX_ZONES: - rep_tlv_buf = cfg_reply_unsigned(tipc_max_zones); - break; - case TIPC_CMD_GET_MAX_CLUSTERS: - rep_tlv_buf = cfg_reply_unsigned(tipc_max_clusters); - break; - case TIPC_CMD_GET_MAX_NODES: - rep_tlv_buf = cfg_reply_unsigned(tipc_max_nodes); - break; - case TIPC_CMD_GET_MAX_SLAVES: - rep_tlv_buf = cfg_reply_unsigned(tipc_max_slaves); - break; - case TIPC_CMD_GET_NETID: - rep_tlv_buf = cfg_reply_unsigned(tipc_net_id); - break; - default: - rep_tlv_buf = NULL; - break; - } - - /* Return reply buffer */ -exit: - spin_unlock_bh(&config_lock); - return rep_tlv_buf; -} - -static void cfg_named_msg_event(void *userdata, - u32 port_ref, - struct sk_buff **buf, - const unchar *msg, - u32 size, - u32 importance, - struct tipc_portid const *orig, - struct tipc_name_seq const *dest) -{ - struct tipc_cfg_msg_hdr *req_hdr; - struct tipc_cfg_msg_hdr *rep_hdr; - struct sk_buff *rep_buf; - - /* Validate configuration message header (ignore invalid message) */ - - req_hdr = (struct tipc_cfg_msg_hdr *)msg; - if ((size < sizeof(*req_hdr)) || - (size != TCM_ALIGN(ntohl(req_hdr->tcm_len))) || - (ntohs(req_hdr->tcm_flags) != TCM_F_REQUEST)) { - warn("discarded invalid configuration message\n"); - return; - } - - /* Generate reply for request (if can't, return request) */ - - rep_buf = cfg_do_cmd(orig->node, - ntohs(req_hdr->tcm_type), - msg + sizeof(*req_hdr), - size - sizeof(*req_hdr), - BUF_HEADROOM + MAX_H_SIZE + sizeof(*rep_hdr)); - if (rep_buf) { - skb_push(rep_buf, sizeof(*rep_hdr)); - rep_hdr = (struct tipc_cfg_msg_hdr *)rep_buf->data; - memcpy(rep_hdr, req_hdr, sizeof(*rep_hdr)); - rep_hdr->tcm_len = htonl(rep_buf->len); - rep_hdr->tcm_flags &= htons(~TCM_F_REQUEST); - } else { - rep_buf = *buf; - *buf = NULL; - } - - /* NEED TO ADD CODE TO HANDLE FAILED SEND (SUCH AS CONGESTION) */ - tipc_send_buf2port(port_ref, orig, rep_buf, rep_buf->len); -} - -int cfg_init(void) -{ - struct tipc_name_seq seq; - int res; - - memset(&mng, 0, sizeof(mng)); - INIT_LIST_HEAD(&mng.link_subscribers); - - res = tipc_attach(&mng.user_ref, 0, 0); - if (res) - goto failed; - - res = tipc_createport(mng.user_ref, 0, TIPC_CRITICAL_IMPORTANCE, - NULL, NULL, NULL, - NULL, cfg_named_msg_event, NULL, - NULL, &mng.port_ref); - if (res) - goto failed; - - seq.type = TIPC_CFG_SRV; - seq.lower = seq.upper = tipc_own_addr; - res = nametbl_publish_rsv(mng.port_ref, TIPC_ZONE_SCOPE, &seq); - if (res) - goto failed; - - return 0; - -failed: - err("Unable to create configuration service\n"); - tipc_detach(mng.user_ref); - mng.user_ref = 0; - return res; -} - -void cfg_stop(void) -{ - if (mng.user_ref) { - tipc_detach(mng.user_ref); - mng.user_ref = 0; - } -} diff --git a/trunk/net/tipc/config.h b/trunk/net/tipc/config.h deleted file mode 100644 index 646377d40454..000000000000 --- a/trunk/net/tipc/config.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * net/tipc/config.h: Include file for TIPC configuration service code - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_CONFIG_H -#define _TIPC_CONFIG_H - -/* ---------------------------------------------------------------------- */ - -#include -#include -#include "link.h" - -struct sk_buff *cfg_reply_alloc(int payload_size); -int cfg_append_tlv(struct sk_buff *buf, int tlv_type, - void *tlv_data, int tlv_data_size); -struct sk_buff *cfg_reply_unsigned_type(u16 tlv_type, u32 value); -struct sk_buff *cfg_reply_string_type(u16 tlv_type, char *string); - -static inline struct sk_buff *cfg_reply_none(void) -{ - return cfg_reply_alloc(0); -} - -static inline struct sk_buff *cfg_reply_unsigned(u32 value) -{ - return cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value); -} - -static inline struct sk_buff *cfg_reply_error_string(char *string) -{ - return cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string); -} - -static inline struct sk_buff *cfg_reply_ultra_string(char *string) -{ - return cfg_reply_string_type(TIPC_TLV_ULTRA_STRING, string); -} - -struct sk_buff *cfg_do_cmd(u32 orig_node, u16 cmd, - const void *req_tlv_area, int req_tlv_space, - int headroom); - -void cfg_link_event(u32 addr, char *name, int up); -int cfg_init(void); -void cfg_stop(void); - -#endif diff --git a/trunk/net/tipc/core.c b/trunk/net/tipc/core.c deleted file mode 100644 index e83ac06e31ba..000000000000 --- a/trunk/net/tipc/core.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * net/tipc/core.c: TIPC module code - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#include "core.h" -#include "dbg.h" -#include "ref.h" -#include "net.h" -#include "user_reg.h" -#include "name_table.h" -#include "subscr.h" -#include "config.h" - -int eth_media_start(void); -void eth_media_stop(void); -int handler_start(void); -void handler_stop(void); -int socket_init(void); -void socket_stop(void); -int netlink_start(void); -void netlink_stop(void); - -#define MOD_NAME "tipc_start: " - -#ifndef CONFIG_TIPC_ZONES -#define CONFIG_TIPC_ZONES 3 -#endif - -#ifndef CONFIG_TIPC_CLUSTERS -#define CONFIG_TIPC_CLUSTERS 1 -#endif - -#ifndef CONFIG_TIPC_NODES -#define CONFIG_TIPC_NODES 255 -#endif - -#ifndef CONFIG_TIPC_SLAVE_NODES -#define CONFIG_TIPC_SLAVE_NODES 0 -#endif - -#ifndef CONFIG_TIPC_PORTS -#define CONFIG_TIPC_PORTS 8191 -#endif - -#ifndef CONFIG_TIPC_LOG -#define CONFIG_TIPC_LOG 0 -#endif - -/* global variables used by multiple sub-systems within TIPC */ - -int tipc_mode = TIPC_NOT_RUNNING; -int tipc_random; -atomic_t tipc_user_count = ATOMIC_INIT(0); - -const char tipc_alphabet[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; - -/* configurable TIPC parameters */ - -u32 tipc_own_addr; -int tipc_max_zones; -int tipc_max_clusters; -int tipc_max_nodes; -int tipc_max_slaves; -int tipc_max_ports; -int tipc_max_subscriptions; -int tipc_max_publications; -int tipc_net_id; -int tipc_remote_management; - - -int tipc_get_mode(void) -{ - return tipc_mode; -} - -/** - * stop_net - shut down TIPC networking sub-systems - */ - -void stop_net(void) -{ - eth_media_stop(); - tipc_stop_net(); -} - -/** - * start_net - start TIPC networking sub-systems - */ - -int start_net(void) -{ - int res; - - if ((res = tipc_start_net()) || - (res = eth_media_start())) { - stop_net(); - } - return res; -} - -/** - * stop_core - switch TIPC from SINGLE NODE to NOT RUNNING mode - */ - -void stop_core(void) -{ - if (tipc_mode != TIPC_NODE_MODE) - return; - - tipc_mode = TIPC_NOT_RUNNING; - - netlink_stop(); - handler_stop(); - cfg_stop(); - subscr_stop(); - reg_stop(); - nametbl_stop(); - ref_table_stop(); - socket_stop(); -} - -/** - * start_core - switch TIPC from NOT RUNNING to SINGLE NODE mode - */ - -int start_core(void) -{ - int res; - - if (tipc_mode != TIPC_NOT_RUNNING) - return -ENOPROTOOPT; - - get_random_bytes(&tipc_random, sizeof(tipc_random)); - tipc_mode = TIPC_NODE_MODE; - - if ((res = handler_start()) || - (res = ref_table_init(tipc_max_ports + tipc_max_subscriptions, - tipc_random)) || - (res = reg_start()) || - (res = nametbl_init()) || - (res = k_signal((Handler)subscr_start, 0)) || - (res = k_signal((Handler)cfg_init, 0)) || - (res = netlink_start()) || - (res = socket_init())) { - stop_core(); - } - return res; -} - - -static int __init tipc_init(void) -{ - int res; - - log_reinit(CONFIG_TIPC_LOG); - info("Activated (compiled " __DATE__ " " __TIME__ ")\n"); - - tipc_own_addr = 0; - tipc_remote_management = 1; - tipc_max_publications = 10000; - tipc_max_subscriptions = 2000; - tipc_max_ports = delimit(CONFIG_TIPC_PORTS, 127, 65536); - tipc_max_zones = delimit(CONFIG_TIPC_ZONES, 1, 511); - tipc_max_clusters = delimit(CONFIG_TIPC_CLUSTERS, 1, 1); - tipc_max_nodes = delimit(CONFIG_TIPC_NODES, 8, 2047); - tipc_max_slaves = delimit(CONFIG_TIPC_SLAVE_NODES, 0, 2047); - tipc_net_id = 4711; - - if ((res = start_core())) - err("Unable to start in single node mode\n"); - else - info("Started in single node mode\n"); - return res; -} - -static void __exit tipc_exit(void) -{ - stop_net(); - stop_core(); - info("Deactivated\n"); - log_stop(); -} - -module_init(tipc_init); -module_exit(tipc_exit); - -MODULE_DESCRIPTION("TIPC: Transparent Inter Process Communication"); -MODULE_LICENSE("Dual BSD/GPL"); - -/* Native TIPC API for kernel-space applications (see tipc.h) */ - -EXPORT_SYMBOL(tipc_attach); -EXPORT_SYMBOL(tipc_detach); -EXPORT_SYMBOL(tipc_get_addr); -EXPORT_SYMBOL(tipc_get_mode); -EXPORT_SYMBOL(tipc_createport); -EXPORT_SYMBOL(tipc_deleteport); -EXPORT_SYMBOL(tipc_ownidentity); -EXPORT_SYMBOL(tipc_portimportance); -EXPORT_SYMBOL(tipc_set_portimportance); -EXPORT_SYMBOL(tipc_portunreliable); -EXPORT_SYMBOL(tipc_set_portunreliable); -EXPORT_SYMBOL(tipc_portunreturnable); -EXPORT_SYMBOL(tipc_set_portunreturnable); -EXPORT_SYMBOL(tipc_publish); -EXPORT_SYMBOL(tipc_withdraw); -EXPORT_SYMBOL(tipc_connect2port); -EXPORT_SYMBOL(tipc_disconnect); -EXPORT_SYMBOL(tipc_shutdown); -EXPORT_SYMBOL(tipc_isconnected); -EXPORT_SYMBOL(tipc_peer); -EXPORT_SYMBOL(tipc_ref_valid); -EXPORT_SYMBOL(tipc_send); -EXPORT_SYMBOL(tipc_send_buf); -EXPORT_SYMBOL(tipc_send2name); -EXPORT_SYMBOL(tipc_forward2name); -EXPORT_SYMBOL(tipc_send_buf2name); -EXPORT_SYMBOL(tipc_forward_buf2name); -EXPORT_SYMBOL(tipc_send2port); -EXPORT_SYMBOL(tipc_forward2port); -EXPORT_SYMBOL(tipc_send_buf2port); -EXPORT_SYMBOL(tipc_forward_buf2port); -EXPORT_SYMBOL(tipc_multicast); -/* EXPORT_SYMBOL(tipc_multicast_buf); not available yet */ -EXPORT_SYMBOL(tipc_ispublished); -EXPORT_SYMBOL(tipc_available_nodes); - -/* TIPC API for external bearers (see tipc_bearer.h) */ - -EXPORT_SYMBOL(tipc_block_bearer); -EXPORT_SYMBOL(tipc_continue); -EXPORT_SYMBOL(tipc_disable_bearer); -EXPORT_SYMBOL(tipc_enable_bearer); -EXPORT_SYMBOL(tipc_recv_msg); -EXPORT_SYMBOL(tipc_register_media); - -/* TIPC API for external APIs (see tipc_port.h) */ - -EXPORT_SYMBOL(tipc_createport_raw); -EXPORT_SYMBOL(tipc_set_msg_option); -EXPORT_SYMBOL(tipc_reject_msg); -EXPORT_SYMBOL(tipc_send_buf_fast); -EXPORT_SYMBOL(tipc_acknowledge); -EXPORT_SYMBOL(tipc_get_port); -EXPORT_SYMBOL(tipc_get_handle); - diff --git a/trunk/net/tipc/core.h b/trunk/net/tipc/core.h deleted file mode 100644 index b69b60b2cc86..000000000000 --- a/trunk/net/tipc/core.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * net/tipc/core.h: Include file for TIPC global declarations - * - * Copyright (c) 2005-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_CORE_H -#define _TIPC_CORE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * TIPC debugging code - */ - -#define assert(i) BUG_ON(!(i)) - -struct tipc_msg; -extern struct print_buf *CONS, *LOG; -extern struct print_buf *TEE(struct print_buf *, struct print_buf *); -void msg_print(struct print_buf*,struct tipc_msg *,const char*); -void tipc_printf(struct print_buf *, const char *fmt, ...); -void tipc_dump(struct print_buf*,const char *fmt, ...); - -#ifdef CONFIG_TIPC_DEBUG - -/* - * TIPC debug support included: - * - system messages are printed to TIPC_OUTPUT print buffer - * - debug messages are printed to DBG_OUTPUT print buffer - */ - -#define err(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_ERR "TIPC: " fmt, ## arg) -#define warn(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_WARNING "TIPC: " fmt, ## arg) -#define info(fmt, arg...) tipc_printf(TIPC_OUTPUT, KERN_NOTICE "TIPC: " fmt, ## arg) - -#define dbg(fmt, arg...) do {if (DBG_OUTPUT) tipc_printf(DBG_OUTPUT, fmt, ## arg);} while(0) -#define msg_dbg(msg, txt) do {if (DBG_OUTPUT) msg_print(DBG_OUTPUT, msg, txt);} while(0) -#define dump(fmt, arg...) do {if (DBG_OUTPUT) tipc_dump(DBG_OUTPUT, fmt, ##arg);} while(0) - - -/* - * By default, TIPC_OUTPUT is defined to be system console and TIPC log buffer, - * while DBG_OUTPUT is the null print buffer. These defaults can be changed - * here, or on a per .c file basis, by redefining these symbols. The following - * print buffer options are available: - * - * NULL : Output to null print buffer (i.e. print nowhere) - * CONS : Output to system console - * LOG : Output to TIPC log buffer - * &buf : Output to user-defined buffer (struct print_buf *) - * TEE(&buf_a,&buf_b) : Output to two print buffers (eg. TEE(CONS,LOG) ) - */ - -#ifndef TIPC_OUTPUT -#define TIPC_OUTPUT TEE(CONS,LOG) -#endif - -#ifndef DBG_OUTPUT -#define DBG_OUTPUT NULL -#endif - -#else - -#ifndef DBG_OUTPUT -#define DBG_OUTPUT NULL -#endif - -/* - * TIPC debug support not included: - * - system messages are printed to system console - * - debug messages are not printed - */ - -#define err(fmt, arg...) printk(KERN_ERR "TIPC: " fmt , ## arg) -#define info(fmt, arg...) printk(KERN_INFO "TIPC: " fmt , ## arg) -#define warn(fmt, arg...) printk(KERN_WARNING "TIPC: " fmt , ## arg) - -#define dbg(fmt, arg...) do {} while (0) -#define msg_dbg(msg,txt) do {} while (0) -#define dump(fmt,arg...) do {} while (0) - -#endif - - -/* - * TIPC-specific error codes - */ - -#define ELINKCONG EAGAIN /* link congestion <=> resource unavailable */ - -/* - * Global configuration variables - */ - -extern u32 tipc_own_addr; -extern int tipc_max_zones; -extern int tipc_max_clusters; -extern int tipc_max_nodes; -extern int tipc_max_slaves; -extern int tipc_max_ports; -extern int tipc_max_subscriptions; -extern int tipc_max_publications; -extern int tipc_net_id; -extern int tipc_remote_management; - -/* - * Other global variables - */ - -extern int tipc_mode; -extern int tipc_random; -extern const char tipc_alphabet[]; -extern atomic_t tipc_user_count; - - -/* - * Routines available to privileged subsystems - */ - -extern int start_core(void); -extern void stop_core(void); -extern int start_net(void); -extern void stop_net(void); - -static inline int delimit(int val, int min, int max) -{ - if (val > max) - return max; - if (val < min) - return min; - return val; -} - - -/* - * TIPC timer and signal code - */ - -typedef void (*Handler) (unsigned long); - -u32 k_signal(Handler routine, unsigned long argument); - -/** - * k_init_timer - initialize a timer - * @timer: pointer to timer structure - * @routine: pointer to routine to invoke when timer expires - * @argument: value to pass to routine when timer expires - * - * Timer must be initialized before use (and terminated when no longer needed). - */ - -static inline void k_init_timer(struct timer_list *timer, Handler routine, - unsigned long argument) -{ - dbg("initializing timer %p\n", timer); - init_timer(timer); - timer->function = routine; - timer->data = argument; -} - -/** - * k_start_timer - start a timer - * @timer: pointer to timer structure - * @msec: time to delay (in ms) - * - * Schedules a previously initialized timer for later execution. - * If timer is already running, the new timeout overrides the previous request. - * - * To ensure the timer doesn't expire before the specified delay elapses, - * the amount of delay is rounded up when converting to the jiffies - * then an additional jiffy is added to account for the fact that - * the starting time may be in the middle of the current jiffy. - */ - -static inline void k_start_timer(struct timer_list *timer, unsigned long msec) -{ - dbg("starting timer %p for %u\n", timer, msec); - mod_timer(timer, jiffies + msecs_to_jiffies(msec) + 1); -} - -/** - * k_cancel_timer - cancel a timer - * @timer: pointer to timer structure - * - * Cancels a previously initialized timer. - * Can be called safely even if the timer is already inactive. - * - * WARNING: Must not be called when holding locks required by the timer's - * timeout routine, otherwise deadlock can occur on SMP systems! - */ - -static inline void k_cancel_timer(struct timer_list *timer) -{ - dbg("cancelling timer %p\n", timer); - del_timer_sync(timer); -} - -/** - * k_term_timer - terminate a timer - * @timer: pointer to timer structure - * - * Prevents further use of a previously initialized timer. - * - * WARNING: Caller must ensure timer isn't currently running. - * - * (Do not "enhance" this routine to automatically cancel an active timer, - * otherwise deadlock can arise when a timeout routine calls k_term_timer.) - */ - -static inline void k_term_timer(struct timer_list *timer) -{ - dbg("terminating timer %p\n", timer); -} - - -/* - * TIPC message buffer code - * - * TIPC message buffer headroom leaves room for 14 byte Ethernet header, - * while ensuring TIPC header is word aligned for quicker access - */ - -#define BUF_HEADROOM 16u - -struct tipc_skb_cb { - void *handle; -}; - -#define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) - - -static inline struct tipc_msg *buf_msg(struct sk_buff *skb) -{ - return (struct tipc_msg *)skb->data; -} - -/** - * buf_acquire - creates a TIPC message buffer - * @size: message size (including TIPC header) - * - * Returns a new buffer. Space is reserved for a data link header. - */ - -static inline struct sk_buff *buf_acquire(u32 size) -{ - struct sk_buff *skb; - unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u; - - skb = alloc_skb(buf_size, GFP_ATOMIC); - if (skb) { - skb_reserve(skb, BUF_HEADROOM); - skb_put(skb, size); - skb->next = NULL; - } - return skb; -} - -/** - * buf_discard - frees a TIPC message buffer - * @skb: message buffer - * - * Frees a new buffer. If passed NULL, just returns. - */ - -static inline void buf_discard(struct sk_buff *skb) -{ - if (likely(skb != NULL)) - kfree_skb(skb); -} - -#endif diff --git a/trunk/net/tipc/dbg.c b/trunk/net/tipc/dbg.c deleted file mode 100644 index 7ed60a1cfbb8..000000000000 --- a/trunk/net/tipc/dbg.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * net/tipc/dbg.c: TIPC print buffer routines for debuggign - * - * Copyright (c) 1996-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "config.h" -#include "dbg.h" - -#define MAX_STRING 512 - -static char print_string[MAX_STRING]; -static spinlock_t print_lock = SPIN_LOCK_UNLOCKED; - -static struct print_buf cons_buf = { NULL, 0, NULL, NULL }; -struct print_buf *CONS = &cons_buf; - -static struct print_buf log_buf = { NULL, 0, NULL, NULL }; -struct print_buf *LOG = &log_buf; - - -#define FORMAT(PTR,LEN,FMT) \ -{\ - va_list args;\ - va_start(args, FMT);\ - LEN = vsprintf(PTR, FMT, args);\ - va_end(args);\ - *(PTR + LEN) = '\0';\ -} - -/* - * Locking policy when using print buffers. - * - * 1) Routines of the form printbuf_XXX() rely on the caller to prevent - * simultaneous use of the print buffer(s) being manipulated. - * 2) tipc_printf() uses 'print_lock' to prevent simultaneous use of - * 'print_string' and to protect its print buffer(s). - * 3) TEE() uses 'print_lock' to protect its print buffer(s). - * 4) Routines of the form log_XXX() uses 'print_lock' to protect LOG. - */ - -/** - * printbuf_init - initialize print buffer to empty - */ - -void printbuf_init(struct print_buf *pb, char *raw, u32 sz) -{ - if (!pb || !raw || (sz < (MAX_STRING + 1))) - return; - - pb->crs = pb->buf = raw; - pb->size = sz; - pb->next = 0; - pb->buf[0] = 0; - pb->buf[sz-1] = ~0; -} - -/** - * printbuf_reset - reinitialize print buffer to empty state - */ - -void printbuf_reset(struct print_buf *pb) -{ - if (pb && pb->buf) - printbuf_init(pb, pb->buf, pb->size); -} - -/** - * printbuf_empty - test if print buffer is in empty state - */ - -int printbuf_empty(struct print_buf *pb) -{ - return (!pb || !pb->buf || (pb->crs == pb->buf)); -} - -/** - * printbuf_validate - check for print buffer overflow - * - * Verifies that a print buffer has captured all data written to it. - * If data has been lost, linearize buffer and prepend an error message - * - * Returns length of print buffer data string (including trailing NULL) - */ - -int printbuf_validate(struct print_buf *pb) -{ - char *err = " *** PRINT BUFFER WRAPPED AROUND ***\n"; - char *cp_buf; - struct print_buf cb; - - if (!pb || !pb->buf) - return 0; - - if (pb->buf[pb->size - 1] == '\0') { - cp_buf = kmalloc(pb->size, GFP_ATOMIC); - if (cp_buf != NULL){ - printbuf_init(&cb, cp_buf, pb->size); - printbuf_move(&cb, pb); - printbuf_move(pb, &cb); - kfree(cp_buf); - memcpy(pb->buf, err, strlen(err)); - } else { - printbuf_reset(pb); - tipc_printf(pb, err); - } - } - return (pb->crs - pb->buf + 1); -} - -/** - * printbuf_move - move print buffer contents to another print buffer - * - * Current contents of destination print buffer (if any) are discarded. - * Source print buffer becomes empty if a successful move occurs. - */ - -void printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) -{ - int len; - - /* Handle the cases where contents can't be moved */ - - if (!pb_to || !pb_to->buf) - return; - - if (!pb_from || !pb_from->buf) { - printbuf_reset(pb_to); - return; - } - - if (pb_to->size < pb_from->size) { - printbuf_reset(pb_to); - tipc_printf(pb_to, "*** PRINT BUFFER OVERFLOW ***"); - return; - } - - /* Copy data from char after cursor to end (if used) */ - len = pb_from->buf + pb_from->size - pb_from->crs - 2; - if ((pb_from->buf[pb_from->size-1] == 0) && (len > 0)) { - strcpy(pb_to->buf, pb_from->crs + 1); - pb_to->crs = pb_to->buf + len; - } else - pb_to->crs = pb_to->buf; - - /* Copy data from start to cursor (always) */ - len = pb_from->crs - pb_from->buf; - strcpy(pb_to->crs, pb_from->buf); - pb_to->crs += len; - - printbuf_reset(pb_from); -} - -/** - * tipc_printf - append formatted output to print buffer chain - */ - -void tipc_printf(struct print_buf *pb, const char *fmt, ...) -{ - int chars_to_add; - int chars_left; - char save_char; - struct print_buf *pb_next; - - spin_lock_bh(&print_lock); - FORMAT(print_string, chars_to_add, fmt); - if (chars_to_add >= MAX_STRING) - strcpy(print_string, "*** STRING TOO LONG ***"); - - while (pb) { - if (pb == CONS) - printk(print_string); - else if (pb->buf) { - chars_left = pb->buf + pb->size - pb->crs - 1; - if (chars_to_add <= chars_left) { - strcpy(pb->crs, print_string); - pb->crs += chars_to_add; - } else { - strcpy(pb->buf, print_string + chars_left); - save_char = print_string[chars_left]; - print_string[chars_left] = 0; - strcpy(pb->crs, print_string); - print_string[chars_left] = save_char; - pb->crs = pb->buf + chars_to_add - chars_left; - } - } - pb_next = pb->next; - pb->next = 0; - pb = pb_next; - } - spin_unlock_bh(&print_lock); -} - -/** - * TEE - perform next output operation on both print buffers - */ - -struct print_buf *TEE(struct print_buf *b0, struct print_buf *b1) -{ - struct print_buf *pb = b0; - - if (!b0 || (b0 == b1)) - return b1; - if (!b1) - return b0; - - spin_lock_bh(&print_lock); - while (pb->next) { - if ((pb->next == b1) || (pb->next == b0)) - pb->next = pb->next->next; - else - pb = pb->next; - } - pb->next = b1; - spin_unlock_bh(&print_lock); - return b0; -} - -/** - * print_to_console - write string of bytes to console in multiple chunks - */ - -static void print_to_console(char *crs, int len) -{ - int rest = len; - - while (rest > 0) { - int sz = rest < MAX_STRING ? rest : MAX_STRING; - char c = crs[sz]; - - crs[sz] = 0; - printk((const char *)crs); - crs[sz] = c; - rest -= sz; - crs += sz; - } -} - -/** - * printbuf_dump - write print buffer contents to console - */ - -static void printbuf_dump(struct print_buf *pb) -{ - int len; - - /* Dump print buffer from char after cursor to end (if used) */ - len = pb->buf + pb->size - pb->crs - 2; - if ((pb->buf[pb->size - 1] == 0) && (len > 0)) - print_to_console(pb->crs + 1, len); - - /* Dump print buffer from start to cursor (always) */ - len = pb->crs - pb->buf; - print_to_console(pb->buf, len); -} - -/** - * tipc_dump - dump non-console print buffer(s) to console - */ - -void tipc_dump(struct print_buf *pb, const char *fmt, ...) -{ - int len; - - spin_lock_bh(&print_lock); - FORMAT(CONS->buf, len, fmt); - printk(CONS->buf); - - for (; pb; pb = pb->next) { - if (pb == CONS) - continue; - printk("\n---- Start of dump,%s log ----\n\n", - (pb == LOG) ? "global" : "local"); - printbuf_dump(pb); - printbuf_reset(pb); - printk("\n-------- End of dump --------\n"); - } - spin_unlock_bh(&print_lock); -} - -/** - * log_stop - free up TIPC log print buffer - */ - -void log_stop(void) -{ - spin_lock_bh(&print_lock); - if (LOG->buf) { - kfree(LOG->buf); - LOG->buf = NULL; - } - spin_unlock_bh(&print_lock); -} - -/** - * log_reinit - set TIPC log print buffer to specified size - */ - -void log_reinit(int log_size) -{ - log_stop(); - - if (log_size) { - if (log_size <= MAX_STRING) - log_size = MAX_STRING + 1; - spin_lock_bh(&print_lock); - printbuf_init(LOG, kmalloc(log_size, GFP_ATOMIC), log_size); - spin_unlock_bh(&print_lock); - } -} - -/** - * log_resize - reconfigure size of TIPC log buffer - */ - -struct sk_buff *log_resize(const void *req_tlv_area, int req_tlv_space) -{ - u32 value; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - value = *(u32 *)TLV_DATA(req_tlv_area); - value = ntohl(value); - if (value != delimit(value, 0, 32768)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (log size must be 0-32768)"); - log_reinit(value); - return cfg_reply_none(); -} - -/** - * log_dump - capture TIPC log buffer contents in configuration message - */ - -struct sk_buff *log_dump(void) -{ - struct sk_buff *reply; - - spin_lock_bh(&print_lock); - if (!LOG->buf) - reply = cfg_reply_ultra_string("log not activated\n"); - else if (printbuf_empty(LOG)) - reply = cfg_reply_ultra_string("log is empty\n"); - else { - struct tlv_desc *rep_tlv; - struct print_buf pb; - int str_len; - - str_len = min(LOG->size, 32768u); - reply = cfg_reply_alloc(TLV_SPACE(str_len)); - if (reply) { - rep_tlv = (struct tlv_desc *)reply->data; - printbuf_init(&pb, TLV_DATA(rep_tlv), str_len); - printbuf_move(&pb, LOG); - str_len = strlen(TLV_DATA(rep_tlv)) + 1; - skb_put(reply, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - } - } - spin_unlock_bh(&print_lock); - return reply; -} - diff --git a/trunk/net/tipc/dbg.h b/trunk/net/tipc/dbg.h deleted file mode 100644 index c6b2a64c224f..000000000000 --- a/trunk/net/tipc/dbg.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * net/tipc/dbg.h: Include file for TIPC print buffer routines - * - * Copyright (c) 1997-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_DBG_H -#define _TIPC_DBG_H - -struct print_buf { - char *buf; - u32 size; - char *crs; - struct print_buf *next; -}; - -void printbuf_init(struct print_buf *pb, char *buf, u32 sz); -void printbuf_reset(struct print_buf *pb); -int printbuf_empty(struct print_buf *pb); -int printbuf_validate(struct print_buf *pb); -void printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); - -void log_reinit(int log_size); -void log_stop(void); - -struct sk_buff *log_resize(const void *req_tlv_area, int req_tlv_space); -struct sk_buff *log_dump(void); - -#endif diff --git a/trunk/net/tipc/discover.c b/trunk/net/tipc/discover.c deleted file mode 100644 index b106ef1621cc..000000000000 --- a/trunk/net/tipc/discover.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * net/tipc/discover.c - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "dbg.h" -#include "link.h" -#include "zone.h" -#include "discover.h" -#include "port.h" -#include "name_table.h" - -#define TIPC_LINK_REQ_INIT 125 /* min delay during bearer start up */ -#define TIPC_LINK_REQ_FAST 2000 /* normal delay if bearer has no links */ -#define TIPC_LINK_REQ_SLOW 600000 /* normal delay if bearer has links */ - -#if 0 -#define GET_NODE_INFO 300 -#define GET_NODE_INFO_RESULT 301 -#define FORWARD_LINK_PROBE 302 -#define LINK_REQUEST_REJECTED 303 -#define LINK_REQUEST_ACCEPTED 304 -#define DROP_LINK_REQUEST 305 -#define CHECK_LINK_COUNT 306 -#endif - -/* - * TODO: Most of the inter-cluster setup stuff should be - * rewritten, and be made conformant with specification. - */ - - -/** - * struct link_req - information about an ongoing link setup request - * @bearer: bearer issuing requests - * @dest: destination address for request messages - * @buf: request message to be (repeatedly) sent - * @timer: timer governing period between requests - * @timer_intv: current interval between requests (in ms) - */ -struct link_req { - struct bearer *bearer; - struct tipc_media_addr dest; - struct sk_buff *buf; - struct timer_list timer; - unsigned int timer_intv; -}; - - -#if 0 -int disc_create_link(const struct tipc_link_create *argv) -{ - /* - * Code for inter cluster link setup here - */ - return TIPC_OK; -} -#endif - -/* - * disc_lost_link(): A link has lost contact - */ - -void disc_link_event(u32 addr, char *name, int up) -{ - if (in_own_cluster(addr)) - return; - /* - * Code for inter cluster link setup here - */ -} - -/** - * disc_init_msg - initialize a link setup message - * @type: message type (request or response) - * @req_links: number of links associated with message - * @dest_domain: network domain of node(s) which should respond to message - * @b_ptr: ptr to bearer issuing message - */ - -struct sk_buff *disc_init_msg(u32 type, - u32 req_links, - u32 dest_domain, - struct bearer *b_ptr) -{ - struct sk_buff *buf = buf_acquire(DSC_H_SIZE); - struct tipc_msg *msg; - - if (buf) { - msg = buf_msg(buf); - msg_init(msg, LINK_CONFIG, type, TIPC_OK, DSC_H_SIZE, - dest_domain); - msg_set_non_seq(msg); - msg_set_req_links(msg, req_links); - msg_set_dest_domain(msg, dest_domain); - msg_set_bc_netid(msg, tipc_net_id); - msg_set_media_addr(msg, &b_ptr->publ.addr); - } - return buf; -} - -/** - * disc_recv_msg - handle incoming link setup message (request or response) - * @buf: buffer containing message - */ - -void disc_recv_msg(struct sk_buff *buf) -{ - struct bearer *b_ptr = (struct bearer *)TIPC_SKB_CB(buf)->handle; - struct link *link; - struct tipc_media_addr media_addr; - struct tipc_msg *msg = buf_msg(buf); - u32 dest = msg_dest_domain(msg); - u32 orig = msg_prevnode(msg); - u32 net_id = msg_bc_netid(msg); - u32 type = msg_type(msg); - - msg_get_media_addr(msg,&media_addr); - msg_dbg(msg, "RECV:"); - buf_discard(buf); - - if (net_id != tipc_net_id) - return; - if (!addr_domain_valid(dest)) - return; - if (!addr_node_valid(orig)) - return; - if (orig == tipc_own_addr) - return; - if (!in_scope(dest, tipc_own_addr)) - return; - if (is_slave(tipc_own_addr) && is_slave(orig)) - return; - if (is_slave(orig) && !in_own_cluster(orig)) - return; - if (in_own_cluster(orig)) { - /* Always accept link here */ - struct sk_buff *rbuf; - struct tipc_media_addr *addr; - struct node *n_ptr = node_find(orig); - int link_up; - dbg(" in own cluster\n"); - if (n_ptr == NULL) { - n_ptr = node_create(orig); - } - if (n_ptr == NULL) { - warn("Memory squeeze; Failed to create node\n"); - return; - } - spin_lock_bh(&n_ptr->lock); - link = n_ptr->links[b_ptr->identity]; - if (!link) { - dbg("creating link\n"); - link = link_create(b_ptr, orig, &media_addr); - if (!link) { - spin_unlock_bh(&n_ptr->lock); - return; - } - } - addr = &link->media_addr; - if (memcmp(addr, &media_addr, sizeof(*addr))) { - char addr_string[16]; - - warn("New bearer address for %s\n", - addr_string_fill(addr_string, orig)); - memcpy(addr, &media_addr, sizeof(*addr)); - link_reset(link); - } - link_up = link_is_up(link); - spin_unlock_bh(&n_ptr->lock); - if ((type == DSC_RESP_MSG) || link_up) - return; - rbuf = disc_init_msg(DSC_RESP_MSG, 1, orig, b_ptr); - if (rbuf != NULL) { - msg_dbg(buf_msg(rbuf),"SEND:"); - b_ptr->media->send_msg(rbuf, &b_ptr->publ, &media_addr); - buf_discard(rbuf); - } - } -} - -/** - * disc_stop_link_req - stop sending periodic link setup requests - * @req: ptr to link request structure - */ - -void disc_stop_link_req(struct link_req *req) -{ - if (!req) - return; - - k_cancel_timer(&req->timer); - k_term_timer(&req->timer); - buf_discard(req->buf); - kfree(req); -} - -/** - * disc_update_link_req - update frequency of periodic link setup requests - * @req: ptr to link request structure - */ - -void disc_update_link_req(struct link_req *req) -{ - if (!req) - return; - - if (req->timer_intv == TIPC_LINK_REQ_SLOW) { - if (!req->bearer->nodes.count) { - req->timer_intv = TIPC_LINK_REQ_FAST; - k_start_timer(&req->timer, req->timer_intv); - } - } else if (req->timer_intv == TIPC_LINK_REQ_FAST) { - if (req->bearer->nodes.count) { - req->timer_intv = TIPC_LINK_REQ_SLOW; - k_start_timer(&req->timer, req->timer_intv); - } - } else { - /* leave timer "as is" if haven't yet reached a "normal" rate */ - } -} - -/** - * disc_timeout - send a periodic link setup request - * @req: ptr to link request structure - * - * Called whenever a link setup request timer associated with a bearer expires. - */ - -static void disc_timeout(struct link_req *req) -{ - spin_lock_bh(&req->bearer->publ.lock); - - req->bearer->media->send_msg(req->buf, &req->bearer->publ, &req->dest); - - if ((req->timer_intv == TIPC_LINK_REQ_SLOW) || - (req->timer_intv == TIPC_LINK_REQ_FAST)) { - /* leave timer interval "as is" if already at a "normal" rate */ - } else { - req->timer_intv *= 2; - if (req->timer_intv > TIPC_LINK_REQ_SLOW) - req->timer_intv = TIPC_LINK_REQ_SLOW; - if ((req->timer_intv == TIPC_LINK_REQ_FAST) && - (req->bearer->nodes.count)) - req->timer_intv = TIPC_LINK_REQ_SLOW; - } - k_start_timer(&req->timer, req->timer_intv); - - spin_unlock_bh(&req->bearer->publ.lock); -} - -/** - * disc_init_link_req - start sending periodic link setup requests - * @b_ptr: ptr to bearer issuing requests - * @dest: destination address for request messages - * @dest_domain: network domain of node(s) which should respond to message - * @req_links: max number of desired links - * - * Returns pointer to link request structure, or NULL if unable to create. - */ - -struct link_req *disc_init_link_req(struct bearer *b_ptr, - const struct tipc_media_addr *dest, - u32 dest_domain, - u32 req_links) -{ - struct link_req *req; - - req = (struct link_req *)kmalloc(sizeof(*req), GFP_ATOMIC); - if (!req) - return NULL; - - req->buf = disc_init_msg(DSC_REQ_MSG, req_links, dest_domain, b_ptr); - if (!req->buf) { - kfree(req); - return NULL; - } - - memcpy(&req->dest, dest, sizeof(*dest)); - req->bearer = b_ptr; - req->timer_intv = TIPC_LINK_REQ_INIT; - k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req); - k_start_timer(&req->timer, req->timer_intv); - return req; -} - diff --git a/trunk/net/tipc/discover.h b/trunk/net/tipc/discover.h deleted file mode 100644 index 2a6114d91626..000000000000 --- a/trunk/net/tipc/discover.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * net/tipc/discover.h - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_DISCOVER_H -#define _TIPC_DISCOVER_H - -#include - -struct link_req; - -struct link_req *disc_init_link_req(struct bearer *b_ptr, - const struct tipc_media_addr *dest, - u32 dest_domain, - u32 req_links); -void disc_update_link_req(struct link_req *req); -void disc_stop_link_req(struct link_req *req); - -void disc_recv_msg(struct sk_buff *buf); - -void disc_link_event(u32 addr, char *name, int up); -#if 0 -int disc_create_link(const struct tipc_link_create *argv); -#endif - -#endif diff --git a/trunk/net/tipc/eth_media.c b/trunk/net/tipc/eth_media.c deleted file mode 100644 index 34d0462db3aa..000000000000 --- a/trunk/net/tipc/eth_media.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * net/tipc/eth_media.c: Ethernet bearer support for TIPC - * - * Copyright (c) 2001-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -#define MAX_ETH_BEARERS 2 -#define TIPC_PROTOCOL 0x88ca -#define ETH_LINK_PRIORITY 10 -#define ETH_LINK_TOLERANCE TIPC_DEF_LINK_TOL - - -/** - * struct eth_bearer - Ethernet bearer data structure - * @bearer: ptr to associated "generic" bearer structure - * @dev: ptr to associated Ethernet network device - * @tipc_packet_type: used in binding TIPC to Ethernet driver - */ - -struct eth_bearer { - struct tipc_bearer *bearer; - struct net_device *dev; - struct packet_type tipc_packet_type; -}; - -static struct eth_bearer eth_bearers[MAX_ETH_BEARERS]; -static int eth_started = 0; -static struct notifier_block notifier; - -/** - * send_msg - send a TIPC message out over an Ethernet interface - */ - -static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, - struct tipc_media_addr *dest) -{ - struct sk_buff *clone; - struct net_device *dev; - - clone = skb_clone(buf, GFP_ATOMIC); - if (clone) { - clone->nh.raw = clone->data; - dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; - clone->dev = dev; - dev->hard_header(clone, dev, TIPC_PROTOCOL, - &dest->dev_addr.eth_addr, - dev->dev_addr, clone->len); - dev_queue_xmit(clone); - } - return TIPC_OK; -} - -/** - * recv_msg - handle incoming TIPC message from an Ethernet interface - * - * Routine truncates any Ethernet padding/CRC appended to the message, - * and ensures message size matches actual length - */ - -static int recv_msg(struct sk_buff *buf, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) -{ - struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; - u32 size; - - if (likely(eb_ptr->bearer)) { - size = msg_size((struct tipc_msg *)buf->data); - skb_trim(buf, size); - if (likely(buf->len == size)) { - buf->next = NULL; - tipc_recv_msg(buf, eb_ptr->bearer); - } else { - kfree_skb(buf); - } - } else { - kfree_skb(buf); - } - return TIPC_OK; -} - -/** - * enable_bearer - attach TIPC bearer to an Ethernet interface - */ - -static int enable_bearer(struct tipc_bearer *tb_ptr) -{ - struct net_device *dev = dev_base; - struct eth_bearer *eb_ptr = ð_bearers[0]; - struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; - char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; - - /* Find device with specified name */ - - while (dev && dev->name && - (memcmp(dev->name, driver_name, strlen(dev->name)))) { - dev = dev->next; - } - if (!dev) - return -ENODEV; - - /* Find Ethernet bearer for device (or create one) */ - - for (;(eb_ptr != stop) && eb_ptr->dev && (eb_ptr->dev != dev); eb_ptr++); - if (eb_ptr == stop) - return -EDQUOT; - if (!eb_ptr->dev) { - eb_ptr->dev = dev; - eb_ptr->tipc_packet_type.type = __constant_htons(TIPC_PROTOCOL); - eb_ptr->tipc_packet_type.dev = dev; - eb_ptr->tipc_packet_type.func = recv_msg; - eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr; - INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list)); - dev_hold(dev); - dev_add_pack(&eb_ptr->tipc_packet_type); - } - - /* Associate TIPC bearer with Ethernet bearer */ - - eb_ptr->bearer = tb_ptr; - tb_ptr->usr_handle = (void *)eb_ptr; - tb_ptr->mtu = dev->mtu; - tb_ptr->blocked = 0; - tb_ptr->addr.type = htonl(TIPC_MEDIA_TYPE_ETH); - memcpy(&tb_ptr->addr.dev_addr, &dev->dev_addr, ETH_ALEN); - return 0; -} - -/** - * disable_bearer - detach TIPC bearer from an Ethernet interface - * - * We really should do dev_remove_pack() here, but this function can not be - * called at tasklet level. => Use eth_bearer->bearer as a flag to throw away - * incoming buffers, & postpone dev_remove_pack() to eth_media_stop() on exit. - */ - -static void disable_bearer(struct tipc_bearer *tb_ptr) -{ - ((struct eth_bearer *)tb_ptr->usr_handle)->bearer = 0; -} - -/** - * recv_notification - handle device updates from OS - * - * Change the state of the Ethernet bearer (if any) associated with the - * specified device. - */ - -static int recv_notification(struct notifier_block *nb, unsigned long evt, - void *dv) -{ - struct net_device *dev = (struct net_device *)dv; - struct eth_bearer *eb_ptr = ð_bearers[0]; - struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; - - while ((eb_ptr->dev != dev)) { - if (++eb_ptr == stop) - return NOTIFY_DONE; /* couldn't find device */ - } - if (!eb_ptr->bearer) - return NOTIFY_DONE; /* bearer had been disabled */ - - eb_ptr->bearer->mtu = dev->mtu; - - switch (evt) { - case NETDEV_CHANGE: - if (netif_carrier_ok(dev)) - tipc_continue(eb_ptr->bearer); - else - tipc_block_bearer(eb_ptr->bearer->name); - break; - case NETDEV_UP: - tipc_continue(eb_ptr->bearer); - break; - case NETDEV_DOWN: - tipc_block_bearer(eb_ptr->bearer->name); - break; - case NETDEV_CHANGEMTU: - case NETDEV_CHANGEADDR: - tipc_block_bearer(eb_ptr->bearer->name); - tipc_continue(eb_ptr->bearer); - break; - case NETDEV_UNREGISTER: - case NETDEV_CHANGENAME: - tipc_disable_bearer(eb_ptr->bearer->name); - break; - } - return NOTIFY_OK; -} - -/** - * eth_addr2str - convert Ethernet address to string - */ - -static char *eth_addr2str(struct tipc_media_addr *a, char *str_buf, int str_size) -{ - unchar *addr = (unchar *)&a->dev_addr; - - if (str_size < 18) - *str_buf = '\0'; - else - sprintf(str_buf, "%02x:%02x:%02x:%02x:%02x:%02x", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - return str_buf; -} - -/** - * eth_media_start - activate Ethernet bearer support - * - * Register Ethernet media type with TIPC bearer code. Also register - * with OS for notifications about device state changes. - */ - -int eth_media_start(void) -{ - struct tipc_media_addr bcast_addr; - int res; - - if (eth_started) - return -EINVAL; - - memset(&bcast_addr, 0xff, sizeof(bcast_addr)); - memset(eth_bearers, 0, sizeof(eth_bearers)); - - res = tipc_register_media(TIPC_MEDIA_TYPE_ETH, "eth", - enable_bearer, disable_bearer, send_msg, - eth_addr2str, &bcast_addr, ETH_LINK_PRIORITY, - ETH_LINK_TOLERANCE, TIPC_DEF_LINK_WIN); - if (res) - return res; - - notifier.notifier_call = &recv_notification; - notifier.priority = 0; - res = register_netdevice_notifier(¬ifier); - if (!res) - eth_started = 1; - return res; -} - -/** - * eth_media_stop - deactivate Ethernet bearer support - */ - -void eth_media_stop(void) -{ - int i; - - if (!eth_started) - return; - - unregister_netdevice_notifier(¬ifier); - for (i = 0; i < MAX_ETH_BEARERS ; i++) { - if (eth_bearers[i].bearer) { - eth_bearers[i].bearer->blocked = 1; - eth_bearers[i].bearer = 0; - } - if (eth_bearers[i].dev) { - dev_remove_pack(ð_bearers[i].tipc_packet_type); - dev_put(eth_bearers[i].dev); - } - } - memset(ð_bearers, 0, sizeof(eth_bearers)); - eth_started = 0; -} diff --git a/trunk/net/tipc/handler.c b/trunk/net/tipc/handler.c deleted file mode 100644 index f320010f8a65..000000000000 --- a/trunk/net/tipc/handler.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * net/tipc/handler.c: TIPC signal handling - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" - -struct queue_item { - struct list_head next_signal; - void (*handler) (unsigned long); - unsigned long data; -}; - -static kmem_cache_t *tipc_queue_item_cache; -static struct list_head signal_queue_head; -static spinlock_t qitem_lock = SPIN_LOCK_UNLOCKED; -static int handler_enabled = 0; - -static void process_signal_queue(unsigned long dummy); - -static DECLARE_TASKLET_DISABLED(tipc_tasklet, process_signal_queue, 0); - - -unsigned int k_signal(Handler routine, unsigned long argument) -{ - struct queue_item *item; - - if (!handler_enabled) { - err("Signal request ignored by handler\n"); - return -ENOPROTOOPT; - } - - spin_lock_bh(&qitem_lock); - item = kmem_cache_alloc(tipc_queue_item_cache, GFP_ATOMIC); - if (!item) { - err("Signal queue out of memory\n"); - spin_unlock_bh(&qitem_lock); - return -ENOMEM; - } - item->handler = routine; - item->data = argument; - list_add_tail(&item->next_signal, &signal_queue_head); - spin_unlock_bh(&qitem_lock); - tasklet_schedule(&tipc_tasklet); - return 0; -} - -static void process_signal_queue(unsigned long dummy) -{ - struct queue_item *__volatile__ item; - struct list_head *l, *n; - - spin_lock_bh(&qitem_lock); - list_for_each_safe(l, n, &signal_queue_head) { - item = list_entry(l, struct queue_item, next_signal); - list_del(&item->next_signal); - spin_unlock_bh(&qitem_lock); - item->handler(item->data); - spin_lock_bh(&qitem_lock); - kmem_cache_free(tipc_queue_item_cache, item); - } - spin_unlock_bh(&qitem_lock); -} - -int handler_start(void) -{ - tipc_queue_item_cache = - kmem_cache_create("tipc_queue_items", sizeof(struct queue_item), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - if (!tipc_queue_item_cache) - return -ENOMEM; - - INIT_LIST_HEAD(&signal_queue_head); - tasklet_enable(&tipc_tasklet); - handler_enabled = 1; - return 0; -} - -void handler_stop(void) -{ - struct list_head *l, *n; - struct queue_item *item; - - if (!handler_enabled) - return; - - handler_enabled = 0; - tasklet_disable(&tipc_tasklet); - tasklet_kill(&tipc_tasklet); - - spin_lock_bh(&qitem_lock); - list_for_each_safe(l, n, &signal_queue_head) { - item = list_entry(l, struct queue_item, next_signal); - list_del(&item->next_signal); - kmem_cache_free(tipc_queue_item_cache, item); - } - spin_unlock_bh(&qitem_lock); - - kmem_cache_destroy(tipc_queue_item_cache); -} - diff --git a/trunk/net/tipc/link.c b/trunk/net/tipc/link.c deleted file mode 100644 index 7265f4be4766..000000000000 --- a/trunk/net/tipc/link.c +++ /dev/null @@ -1,3167 +0,0 @@ -/* - * net/tipc/link.c: TIPC link code - * - * Copyright (c) 1996-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "dbg.h" -#include "link.h" -#include "net.h" -#include "node.h" -#include "port.h" -#include "addr.h" -#include "node_subscr.h" -#include "name_distr.h" -#include "bearer.h" -#include "name_table.h" -#include "discover.h" -#include "config.h" -#include "bcast.h" - - -/* - * Limit for deferred reception queue: - */ - -#define DEF_QUEUE_LIMIT 256u - -/* - * Link state events: - */ - -#define STARTING_EVT 856384768 /* link processing trigger */ -#define TRAFFIC_MSG_EVT 560815u /* rx'd ??? */ -#define TIMEOUT_EVT 560817u /* link timer expired */ - -/* - * The following two 'message types' is really just implementation - * data conveniently stored in the message header. - * They must not be considered part of the protocol - */ -#define OPEN_MSG 0 -#define CLOSED_MSG 1 - -/* - * State value stored in 'exp_msg_count' - */ - -#define START_CHANGEOVER 100000u - -/** - * struct link_name - deconstructed link name - * @addr_local: network address of node at this end - * @if_local: name of interface at this end - * @addr_peer: network address of node at far end - * @if_peer: name of interface at far end - */ - -struct link_name { - u32 addr_local; - char if_local[TIPC_MAX_IF_NAME]; - u32 addr_peer; - char if_peer[TIPC_MAX_IF_NAME]; -}; - -#if 0 - -/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ - -/** - * struct link_event - link up/down event notification - */ - -struct link_event { - u32 addr; - int up; - void (*fcn)(u32, char *, int); - char name[TIPC_MAX_LINK_NAME]; -}; - -#endif - -static void link_handle_out_of_seq_msg(struct link *l_ptr, - struct sk_buff *buf); -static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf); -static int link_recv_changeover_msg(struct link **l_ptr, struct sk_buff **buf); -static void link_set_supervision_props(struct link *l_ptr, u32 tolerance); -static int link_send_sections_long(struct port *sender, - struct iovec const *msg_sect, - u32 num_sect, u32 destnode); -static void link_check_defragm_bufs(struct link *l_ptr); -static void link_state_event(struct link *l_ptr, u32 event); -static void link_reset_statistics(struct link *l_ptr); -static void link_print(struct link *l_ptr, struct print_buf *buf, - const char *str); - -/* - * Debugging code used by link routines only - * - * When debugging link problems on a system that has multiple links, - * the standard TIPC debugging routines may not be useful since they - * allow the output from multiple links to be intermixed. For this reason - * routines of the form "dbg_link_XXX()" have been created that will capture - * debug info into a link's personal print buffer, which can then be dumped - * into the TIPC system log (LOG) upon request. - * - * To enable per-link debugging, use LINK_LOG_BUF_SIZE to specify the size - * of the print buffer used by each link. If LINK_LOG_BUF_SIZE is set to 0, - * the dbg_link_XXX() routines simply send their output to the standard - * debug print buffer (DBG_OUTPUT), if it has been defined; this can be useful - * when there is only a single link in the system being debugged. - * - * Notes: - * - When enabled, LINK_LOG_BUF_SIZE should be set to at least 1000 (bytes) - * - "l_ptr" must be valid when using dbg_link_XXX() macros - */ - -#define LINK_LOG_BUF_SIZE 0 - -#define dbg_link(fmt, arg...) do {if (LINK_LOG_BUF_SIZE) tipc_printf(&l_ptr->print_buf, fmt, ## arg); } while(0) -#define dbg_link_msg(msg, txt) do {if (LINK_LOG_BUF_SIZE) msg_print(&l_ptr->print_buf, msg, txt); } while(0) -#define dbg_link_state(txt) do {if (LINK_LOG_BUF_SIZE) link_print(l_ptr, &l_ptr->print_buf, txt); } while(0) -#define dbg_link_dump() do { \ - if (LINK_LOG_BUF_SIZE) { \ - tipc_printf(LOG, "\n\nDumping link <%s>:\n", l_ptr->name); \ - printbuf_move(LOG, &l_ptr->print_buf); \ - } \ -} while (0) - -static inline void dbg_print_link(struct link *l_ptr, const char *str) -{ - if (DBG_OUTPUT) - link_print(l_ptr, DBG_OUTPUT, str); -} - -static inline void dbg_print_buf_chain(struct sk_buff *root_buf) -{ - if (DBG_OUTPUT) { - struct sk_buff *buf = root_buf; - - while (buf) { - msg_dbg(buf_msg(buf), "In chain: "); - buf = buf->next; - } - } -} - -/* - * Simple inlined link routines - */ - -static inline unsigned int align(unsigned int i) -{ - return (i + 3) & ~3u; -} - -static inline int link_working_working(struct link *l_ptr) -{ - return (l_ptr->state == WORKING_WORKING); -} - -static inline int link_working_unknown(struct link *l_ptr) -{ - return (l_ptr->state == WORKING_UNKNOWN); -} - -static inline int link_reset_unknown(struct link *l_ptr) -{ - return (l_ptr->state == RESET_UNKNOWN); -} - -static inline int link_reset_reset(struct link *l_ptr) -{ - return (l_ptr->state == RESET_RESET); -} - -static inline int link_blocked(struct link *l_ptr) -{ - return (l_ptr->exp_msg_count || l_ptr->blocked); -} - -static inline int link_congested(struct link *l_ptr) -{ - return (l_ptr->out_queue_size >= l_ptr->queue_limit[0]); -} - -static inline u32 link_max_pkt(struct link *l_ptr) -{ - return l_ptr->max_pkt; -} - -static inline void link_init_max_pkt(struct link *l_ptr) -{ - u32 max_pkt; - - max_pkt = (l_ptr->b_ptr->publ.mtu & ~3); - if (max_pkt > MAX_MSG_SIZE) - max_pkt = MAX_MSG_SIZE; - - l_ptr->max_pkt_target = max_pkt; - if (l_ptr->max_pkt_target < MAX_PKT_DEFAULT) - l_ptr->max_pkt = l_ptr->max_pkt_target; - else - l_ptr->max_pkt = MAX_PKT_DEFAULT; - - l_ptr->max_pkt_probes = 0; -} - -static inline u32 link_next_sent(struct link *l_ptr) -{ - if (l_ptr->next_out) - return msg_seqno(buf_msg(l_ptr->next_out)); - return mod(l_ptr->next_out_no); -} - -static inline u32 link_last_sent(struct link *l_ptr) -{ - return mod(link_next_sent(l_ptr) - 1); -} - -/* - * Simple non-inlined link routines (i.e. referenced outside this file) - */ - -int link_is_up(struct link *l_ptr) -{ - if (!l_ptr) - return 0; - return (link_working_working(l_ptr) || link_working_unknown(l_ptr)); -} - -int link_is_active(struct link *l_ptr) -{ - return ((l_ptr->owner->active_links[0] == l_ptr) || - (l_ptr->owner->active_links[1] == l_ptr)); -} - -/** - * link_name_validate - validate & (optionally) deconstruct link name - * @name - ptr to link name string - * @name_parts - ptr to area for link name components (or NULL if not needed) - * - * Returns 1 if link name is valid, otherwise 0. - */ - -static int link_name_validate(const char *name, struct link_name *name_parts) -{ - char name_copy[TIPC_MAX_LINK_NAME]; - char *addr_local; - char *if_local; - char *addr_peer; - char *if_peer; - char dummy; - u32 z_local, c_local, n_local; - u32 z_peer, c_peer, n_peer; - u32 if_local_len; - u32 if_peer_len; - - /* copy link name & ensure length is OK */ - - name_copy[TIPC_MAX_LINK_NAME - 1] = 0; - /* need above in case non-Posix strncpy() doesn't pad with nulls */ - strncpy(name_copy, name, TIPC_MAX_LINK_NAME); - if (name_copy[TIPC_MAX_LINK_NAME - 1] != 0) - return 0; - - /* ensure all component parts of link name are present */ - - addr_local = name_copy; - if ((if_local = strchr(addr_local, ':')) == NULL) - return 0; - *(if_local++) = 0; - if ((addr_peer = strchr(if_local, '-')) == NULL) - return 0; - *(addr_peer++) = 0; - if_local_len = addr_peer - if_local; - if ((if_peer = strchr(addr_peer, ':')) == NULL) - return 0; - *(if_peer++) = 0; - if_peer_len = strlen(if_peer) + 1; - - /* validate component parts of link name */ - - if ((sscanf(addr_local, "%u.%u.%u%c", - &z_local, &c_local, &n_local, &dummy) != 3) || - (sscanf(addr_peer, "%u.%u.%u%c", - &z_peer, &c_peer, &n_peer, &dummy) != 3) || - (z_local > 255) || (c_local > 4095) || (n_local > 4095) || - (z_peer > 255) || (c_peer > 4095) || (n_peer > 4095) || - (if_local_len <= 1) || (if_local_len > TIPC_MAX_IF_NAME) || - (if_peer_len <= 1) || (if_peer_len > TIPC_MAX_IF_NAME) || - (strspn(if_local, tipc_alphabet) != (if_local_len - 1)) || - (strspn(if_peer, tipc_alphabet) != (if_peer_len - 1))) - return 0; - - /* return link name components, if necessary */ - - if (name_parts) { - name_parts->addr_local = tipc_addr(z_local, c_local, n_local); - strcpy(name_parts->if_local, if_local); - name_parts->addr_peer = tipc_addr(z_peer, c_peer, n_peer); - strcpy(name_parts->if_peer, if_peer); - } - return 1; -} - -/** - * link_timeout - handle expiration of link timer - * @l_ptr: pointer to link - * - * This routine must not grab "net_lock" to avoid a potential deadlock conflict - * with link_delete(). (There is no risk that the node will be deleted by - * another thread because link_delete() always cancels the link timer before - * node_delete() is called.) - */ - -static void link_timeout(struct link *l_ptr) -{ - node_lock(l_ptr->owner); - - /* update counters used in statistical profiling of send traffic */ - - l_ptr->stats.accu_queue_sz += l_ptr->out_queue_size; - l_ptr->stats.queue_sz_counts++; - - if (l_ptr->out_queue_size > l_ptr->stats.max_queue_sz) - l_ptr->stats.max_queue_sz = l_ptr->out_queue_size; - - if (l_ptr->first_out) { - struct tipc_msg *msg = buf_msg(l_ptr->first_out); - u32 length = msg_size(msg); - - if ((msg_user(msg) == MSG_FRAGMENTER) - && (msg_type(msg) == FIRST_FRAGMENT)) { - length = msg_size(msg_get_wrapped(msg)); - } - if (length) { - l_ptr->stats.msg_lengths_total += length; - l_ptr->stats.msg_length_counts++; - if (length <= 64) - l_ptr->stats.msg_length_profile[0]++; - else if (length <= 256) - l_ptr->stats.msg_length_profile[1]++; - else if (length <= 1024) - l_ptr->stats.msg_length_profile[2]++; - else if (length <= 4096) - l_ptr->stats.msg_length_profile[3]++; - else if (length <= 16384) - l_ptr->stats.msg_length_profile[4]++; - else if (length <= 32768) - l_ptr->stats.msg_length_profile[5]++; - else - l_ptr->stats.msg_length_profile[6]++; - } - } - - /* do all other link processing performed on a periodic basis */ - - link_check_defragm_bufs(l_ptr); - - link_state_event(l_ptr, TIMEOUT_EVT); - - if (l_ptr->next_out) - link_push_queue(l_ptr); - - node_unlock(l_ptr->owner); -} - -static inline void link_set_timer(struct link *l_ptr, u32 time) -{ - k_start_timer(&l_ptr->timer, time); -} - -/** - * link_create - create a new link - * @b_ptr: pointer to associated bearer - * @peer: network address of node at other end of link - * @media_addr: media address to use when sending messages over link - * - * Returns pointer to link. - */ - -struct link *link_create(struct bearer *b_ptr, const u32 peer, - const struct tipc_media_addr *media_addr) -{ - struct link *l_ptr; - struct tipc_msg *msg; - char *if_name; - - l_ptr = (struct link *)kmalloc(sizeof(*l_ptr), GFP_ATOMIC); - if (!l_ptr) { - warn("Memory squeeze; Failed to create link\n"); - return NULL; - } - memset(l_ptr, 0, sizeof(*l_ptr)); - - l_ptr->addr = peer; - if_name = strchr(b_ptr->publ.name, ':') + 1; - sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", - tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), - tipc_node(tipc_own_addr), - if_name, - tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); - /* note: peer i/f is appended to link name by reset/activate */ - memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); - k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); - list_add_tail(&l_ptr->link_list, &b_ptr->links); - l_ptr->checkpoint = 1; - l_ptr->b_ptr = b_ptr; - link_set_supervision_props(l_ptr, b_ptr->media->tolerance); - l_ptr->state = RESET_UNKNOWN; - - l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; - msg = l_ptr->pmsg; - msg_init(msg, LINK_PROTOCOL, RESET_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); - msg_set_size(msg, sizeof(l_ptr->proto_msg)); - msg_set_session(msg, tipc_random); - msg_set_bearer_id(msg, b_ptr->identity); - strcpy((char *)msg_data(msg), if_name); - - l_ptr->priority = b_ptr->priority; - link_set_queue_limits(l_ptr, b_ptr->media->window); - - link_init_max_pkt(l_ptr); - - l_ptr->next_out_no = 1; - INIT_LIST_HEAD(&l_ptr->waiting_ports); - - link_reset_statistics(l_ptr); - - l_ptr->owner = node_attach_link(l_ptr); - if (!l_ptr->owner) { - kfree(l_ptr); - return NULL; - } - - if (LINK_LOG_BUF_SIZE) { - char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); - - if (!pb) { - kfree(l_ptr); - warn("Memory squeeze; Failed to create link\n"); - return NULL; - } - printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE); - } - - k_signal((Handler)link_start, (unsigned long)l_ptr); - - dbg("link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n", - l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit); - - return l_ptr; -} - -/** - * link_delete - delete a link - * @l_ptr: pointer to link - * - * Note: 'net_lock' is write_locked, bearer is locked. - * This routine must not grab the node lock until after link timer cancellation - * to avoid a potential deadlock situation. - */ - -void link_delete(struct link *l_ptr) -{ - if (!l_ptr) { - err("Attempt to delete non-existent link\n"); - return; - } - - dbg("link_delete()\n"); - - k_cancel_timer(&l_ptr->timer); - - node_lock(l_ptr->owner); - link_reset(l_ptr); - node_detach_link(l_ptr->owner, l_ptr); - link_stop(l_ptr); - list_del_init(&l_ptr->link_list); - if (LINK_LOG_BUF_SIZE) - kfree(l_ptr->print_buf.buf); - node_unlock(l_ptr->owner); - k_term_timer(&l_ptr->timer); - kfree(l_ptr); -} - -void link_start(struct link *l_ptr) -{ - dbg("link_start %x\n", l_ptr); - link_state_event(l_ptr, STARTING_EVT); -} - -/** - * link_schedule_port - schedule port for deferred sending - * @l_ptr: pointer to link - * @origport: reference to sending port - * @sz: amount of data to be sent - * - * Schedules port for renewed sending of messages after link congestion - * has abated. - */ - -static int link_schedule_port(struct link *l_ptr, u32 origport, u32 sz) -{ - struct port *p_ptr; - - spin_lock_bh(&port_list_lock); - p_ptr = port_lock(origport); - if (p_ptr) { - if (!p_ptr->wakeup) - goto exit; - if (!list_empty(&p_ptr->wait_list)) - goto exit; - p_ptr->congested_link = l_ptr; - p_ptr->publ.congested = 1; - p_ptr->waiting_pkts = 1 + ((sz - 1) / link_max_pkt(l_ptr)); - list_add_tail(&p_ptr->wait_list, &l_ptr->waiting_ports); - l_ptr->stats.link_congs++; -exit: - port_unlock(p_ptr); - } - spin_unlock_bh(&port_list_lock); - return -ELINKCONG; -} - -void link_wakeup_ports(struct link *l_ptr, int all) -{ - struct port *p_ptr; - struct port *temp_p_ptr; - int win = l_ptr->queue_limit[0] - l_ptr->out_queue_size; - - if (all) - win = 100000; - if (win <= 0) - return; - if (!spin_trylock_bh(&port_list_lock)) - return; - if (link_congested(l_ptr)) - goto exit; - list_for_each_entry_safe(p_ptr, temp_p_ptr, &l_ptr->waiting_ports, - wait_list) { - if (win <= 0) - break; - list_del_init(&p_ptr->wait_list); - p_ptr->congested_link = 0; - assert(p_ptr->wakeup); - spin_lock_bh(p_ptr->publ.lock); - p_ptr->publ.congested = 0; - p_ptr->wakeup(&p_ptr->publ); - win -= p_ptr->waiting_pkts; - spin_unlock_bh(p_ptr->publ.lock); - } - -exit: - spin_unlock_bh(&port_list_lock); -} - -/** - * link_release_outqueue - purge link's outbound message queue - * @l_ptr: pointer to link - */ - -static void link_release_outqueue(struct link *l_ptr) -{ - struct sk_buff *buf = l_ptr->first_out; - struct sk_buff *next; - - while (buf) { - next = buf->next; - buf_discard(buf); - buf = next; - } - l_ptr->first_out = NULL; - l_ptr->out_queue_size = 0; -} - -/** - * link_reset_fragments - purge link's inbound message fragments queue - * @l_ptr: pointer to link - */ - -void link_reset_fragments(struct link *l_ptr) -{ - struct sk_buff *buf = l_ptr->defragm_buf; - struct sk_buff *next; - - while (buf) { - next = buf->next; - buf_discard(buf); - buf = next; - } - l_ptr->defragm_buf = NULL; -} - -/** - * link_stop - purge all inbound and outbound messages associated with link - * @l_ptr: pointer to link - */ - -void link_stop(struct link *l_ptr) -{ - struct sk_buff *buf; - struct sk_buff *next; - - buf = l_ptr->oldest_deferred_in; - while (buf) { - next = buf->next; - buf_discard(buf); - buf = next; - } - - buf = l_ptr->first_out; - while (buf) { - next = buf->next; - buf_discard(buf); - buf = next; - } - - link_reset_fragments(l_ptr); - - buf_discard(l_ptr->proto_msg_queue); - l_ptr->proto_msg_queue = NULL; -} - -#if 0 - -/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ - -static void link_recv_event(struct link_event *ev) -{ - ev->fcn(ev->addr, ev->name, ev->up); - kfree(ev); -} - -static void link_send_event(void (*fcn)(u32 a, char *n, int up), - struct link *l_ptr, int up) -{ - struct link_event *ev; - - ev = kmalloc(sizeof(*ev), GFP_ATOMIC); - if (!ev) { - warn("Link event allocation failure\n"); - return; - } - ev->addr = l_ptr->addr; - ev->up = up; - ev->fcn = fcn; - memcpy(ev->name, l_ptr->name, TIPC_MAX_LINK_NAME); - k_signal((Handler)link_recv_event, (unsigned long)ev); -} - -#else - -#define link_send_event(fcn, l_ptr, up) do { } while (0) - -#endif - -void link_reset(struct link *l_ptr) -{ - struct sk_buff *buf; - u32 prev_state = l_ptr->state; - u32 checkpoint = l_ptr->next_in_no; - - msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1); - - /* Link is down, accept any session: */ - l_ptr->peer_session = 0; - - /* Prepare for max packet size negotiation */ - link_init_max_pkt(l_ptr); - - l_ptr->state = RESET_UNKNOWN; - dbg_link_state("Resetting Link\n"); - - if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET)) - return; - - node_link_down(l_ptr->owner, l_ptr); - bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); -#if 0 - tipc_printf(CONS, "\nReset link <%s>\n", l_ptr->name); - dbg_link_dump(); -#endif - if (node_has_active_links(l_ptr->owner) && - l_ptr->owner->permit_changeover) { - l_ptr->reset_checkpoint = checkpoint; - l_ptr->exp_msg_count = START_CHANGEOVER; - } - - /* Clean up all queues: */ - - link_release_outqueue(l_ptr); - buf_discard(l_ptr->proto_msg_queue); - l_ptr->proto_msg_queue = NULL; - buf = l_ptr->oldest_deferred_in; - while (buf) { - struct sk_buff *next = buf->next; - buf_discard(buf); - buf = next; - } - if (!list_empty(&l_ptr->waiting_ports)) - link_wakeup_ports(l_ptr, 1); - - l_ptr->retransm_queue_head = 0; - l_ptr->retransm_queue_size = 0; - l_ptr->last_out = NULL; - l_ptr->first_out = NULL; - l_ptr->next_out = NULL; - l_ptr->unacked_window = 0; - l_ptr->checkpoint = 1; - l_ptr->next_out_no = 1; - l_ptr->deferred_inqueue_sz = 0; - l_ptr->oldest_deferred_in = NULL; - l_ptr->newest_deferred_in = NULL; - l_ptr->fsm_msg_cnt = 0; - l_ptr->stale_count = 0; - link_reset_statistics(l_ptr); - - link_send_event(cfg_link_event, l_ptr, 0); - if (!in_own_cluster(l_ptr->addr)) - link_send_event(disc_link_event, l_ptr, 0); -} - - -static void link_activate(struct link *l_ptr) -{ - l_ptr->next_in_no = 1; - node_link_up(l_ptr->owner, l_ptr); - bearer_add_dest(l_ptr->b_ptr, l_ptr->addr); - link_send_event(cfg_link_event, l_ptr, 1); - if (!in_own_cluster(l_ptr->addr)) - link_send_event(disc_link_event, l_ptr, 1); -} - -/** - * link_state_event - link finite state machine - * @l_ptr: pointer to link - * @event: state machine event to process - */ - -static void link_state_event(struct link *l_ptr, unsigned event) -{ - struct link *other; - u32 cont_intv = l_ptr->continuity_interval; - - if (!l_ptr->started && (event != STARTING_EVT)) - return; /* Not yet. */ - - if (link_blocked(l_ptr)) { - if (event == TIMEOUT_EVT) { - link_set_timer(l_ptr, cont_intv); - } - return; /* Changeover going on */ - } - dbg_link("STATE_EV: <%s> ", l_ptr->name); - - switch (l_ptr->state) { - case WORKING_WORKING: - dbg_link("WW/"); - switch (event) { - case TRAFFIC_MSG_EVT: - dbg_link("TRF-"); - /* fall through */ - case ACTIVATE_MSG: - dbg_link("ACT\n"); - break; - case TIMEOUT_EVT: - dbg_link("TIM "); - if (l_ptr->next_in_no != l_ptr->checkpoint) { - l_ptr->checkpoint = l_ptr->next_in_no; - if (bclink_acks_missing(l_ptr->owner)) { - link_send_proto_msg(l_ptr, STATE_MSG, - 0, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - } else if (l_ptr->max_pkt < l_ptr->max_pkt_target) { - link_send_proto_msg(l_ptr, STATE_MSG, - 1, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - } - link_set_timer(l_ptr, cont_intv); - break; - } - dbg_link(" -> WU\n"); - l_ptr->state = WORKING_UNKNOWN; - l_ptr->fsm_msg_cnt = 0; - link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv / 4); - break; - case RESET_MSG: - dbg_link("RES -> RR\n"); - link_reset(l_ptr); - l_ptr->state = RESET_RESET; - l_ptr->fsm_msg_cnt = 0; - link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv); - break; - default: - err("Unknown link event %u in WW state\n", event); - } - break; - case WORKING_UNKNOWN: - dbg_link("WU/"); - switch (event) { - case TRAFFIC_MSG_EVT: - dbg_link("TRF-"); - case ACTIVATE_MSG: - dbg_link("ACT -> WW\n"); - l_ptr->state = WORKING_WORKING; - l_ptr->fsm_msg_cnt = 0; - link_set_timer(l_ptr, cont_intv); - break; - case RESET_MSG: - dbg_link("RES -> RR\n"); - link_reset(l_ptr); - l_ptr->state = RESET_RESET; - l_ptr->fsm_msg_cnt = 0; - link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv); - break; - case TIMEOUT_EVT: - dbg_link("TIM "); - if (l_ptr->next_in_no != l_ptr->checkpoint) { - dbg_link("-> WW \n"); - l_ptr->state = WORKING_WORKING; - l_ptr->fsm_msg_cnt = 0; - l_ptr->checkpoint = l_ptr->next_in_no; - if (bclink_acks_missing(l_ptr->owner)) { - link_send_proto_msg(l_ptr, STATE_MSG, - 0, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - } - link_set_timer(l_ptr, cont_intv); - } else if (l_ptr->fsm_msg_cnt < l_ptr->abort_limit) { - dbg_link("Probing %u/%u,timer = %u ms)\n", - l_ptr->fsm_msg_cnt, l_ptr->abort_limit, - cont_intv / 4); - link_send_proto_msg(l_ptr, STATE_MSG, - 1, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv / 4); - } else { /* Link has failed */ - dbg_link("-> RU (%u probes unanswered)\n", - l_ptr->fsm_msg_cnt); - link_reset(l_ptr); - l_ptr->state = RESET_UNKNOWN; - l_ptr->fsm_msg_cnt = 0; - link_send_proto_msg(l_ptr, RESET_MSG, - 0, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv); - } - break; - default: - err("Unknown link event %u in WU state\n", event); - } - break; - case RESET_UNKNOWN: - dbg_link("RU/"); - switch (event) { - case TRAFFIC_MSG_EVT: - dbg_link("TRF-\n"); - break; - case ACTIVATE_MSG: - other = l_ptr->owner->active_links[0]; - if (other && link_working_unknown(other)) { - dbg_link("ACT\n"); - break; - } - dbg_link("ACT -> WW\n"); - l_ptr->state = WORKING_WORKING; - l_ptr->fsm_msg_cnt = 0; - link_activate(l_ptr); - link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv); - break; - case RESET_MSG: - dbg_link("RES \n"); - dbg_link(" -> RR\n"); - l_ptr->state = RESET_RESET; - l_ptr->fsm_msg_cnt = 0; - link_send_proto_msg(l_ptr, ACTIVATE_MSG, 1, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv); - break; - case STARTING_EVT: - dbg_link("START-"); - l_ptr->started = 1; - /* fall through */ - case TIMEOUT_EVT: - dbg_link("TIM \n"); - link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv); - break; - default: - err("Unknown link event %u in RU state\n", event); - } - break; - case RESET_RESET: - dbg_link("RR/ "); - switch (event) { - case TRAFFIC_MSG_EVT: - dbg_link("TRF-"); - /* fall through */ - case ACTIVATE_MSG: - other = l_ptr->owner->active_links[0]; - if (other && link_working_unknown(other)) { - dbg_link("ACT\n"); - break; - } - dbg_link("ACT -> WW\n"); - l_ptr->state = WORKING_WORKING; - l_ptr->fsm_msg_cnt = 0; - link_activate(l_ptr); - link_send_proto_msg(l_ptr, STATE_MSG, 1, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv); - break; - case RESET_MSG: - dbg_link("RES\n"); - break; - case TIMEOUT_EVT: - dbg_link("TIM\n"); - link_send_proto_msg(l_ptr, ACTIVATE_MSG, 0, 0, 0, 0, 0); - l_ptr->fsm_msg_cnt++; - link_set_timer(l_ptr, cont_intv); - dbg_link("fsm_msg_cnt %u\n", l_ptr->fsm_msg_cnt); - break; - default: - err("Unknown link event %u in RR state\n", event); - } - break; - default: - err("Unknown link state %u/%u\n", l_ptr->state, event); - } -} - -/* - * link_bundle_buf(): Append contents of a buffer to - * the tail of an existing one. - */ - -static int link_bundle_buf(struct link *l_ptr, - struct sk_buff *bundler, - struct sk_buff *buf) -{ - struct tipc_msg *bundler_msg = buf_msg(bundler); - struct tipc_msg *msg = buf_msg(buf); - u32 size = msg_size(msg); - u32 to_pos = align(msg_size(bundler_msg)); - u32 rest = link_max_pkt(l_ptr) - to_pos; - - if (msg_user(bundler_msg) != MSG_BUNDLER) - return 0; - if (msg_type(bundler_msg) != OPEN_MSG) - return 0; - if (rest < align(size)) - return 0; - - skb_put(bundler, (to_pos - msg_size(bundler_msg)) + size); - memcpy(bundler->data + to_pos, buf->data, size); - msg_set_size(bundler_msg, to_pos + size); - msg_set_msgcnt(bundler_msg, msg_msgcnt(bundler_msg) + 1); - dbg("Packed msg # %u(%u octets) into pos %u in buf(#%u)\n", - msg_msgcnt(bundler_msg), size, to_pos, msg_seqno(bundler_msg)); - msg_dbg(msg, "PACKD:"); - buf_discard(buf); - l_ptr->stats.sent_bundled++; - return 1; -} - -static inline void link_add_to_outqueue(struct link *l_ptr, - struct sk_buff *buf, - struct tipc_msg *msg) -{ - u32 ack = mod(l_ptr->next_in_no - 1); - u32 seqno = mod(l_ptr->next_out_no++); - - msg_set_word(msg, 2, ((ack << 16) | seqno)); - msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); - buf->next = NULL; - if (l_ptr->first_out) { - l_ptr->last_out->next = buf; - l_ptr->last_out = buf; - } else - l_ptr->first_out = l_ptr->last_out = buf; - l_ptr->out_queue_size++; -} - -/* - * link_send_buf() is the 'full path' for messages, called from - * inside TIPC when the 'fast path' in tipc_send_buf - * has failed, and from link_send() - */ - -int link_send_buf(struct link *l_ptr, struct sk_buff *buf) -{ - struct tipc_msg *msg = buf_msg(buf); - u32 size = msg_size(msg); - u32 dsz = msg_data_sz(msg); - u32 queue_size = l_ptr->out_queue_size; - u32 imp = msg_tot_importance(msg); - u32 queue_limit = l_ptr->queue_limit[imp]; - u32 max_packet = link_max_pkt(l_ptr); - - msg_set_prevnode(msg, tipc_own_addr); /* If routed message */ - - /* Match msg importance against queue limits: */ - - if (unlikely(queue_size >= queue_limit)) { - if (imp <= TIPC_CRITICAL_IMPORTANCE) { - return link_schedule_port(l_ptr, msg_origport(msg), - size); - } - msg_dbg(msg, "TIPC: Congestion, throwing away\n"); - buf_discard(buf); - if (imp > CONN_MANAGER) { - warn("Resetting <%s>, send queue full", l_ptr->name); - link_reset(l_ptr); - } - return dsz; - } - - /* Fragmentation needed ? */ - - if (size > max_packet) - return link_send_long_buf(l_ptr, buf); - - /* Packet can be queued or sent: */ - - if (queue_size > l_ptr->stats.max_queue_sz) - l_ptr->stats.max_queue_sz = queue_size; - - if (likely(!bearer_congested(l_ptr->b_ptr, l_ptr) && - !link_congested(l_ptr))) { - link_add_to_outqueue(l_ptr, buf, msg); - - if (likely(bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr))) { - l_ptr->unacked_window = 0; - } else { - bearer_schedule(l_ptr->b_ptr, l_ptr); - l_ptr->stats.bearer_congs++; - l_ptr->next_out = buf; - } - return dsz; - } - /* Congestion: can message be bundled ?: */ - - if ((msg_user(msg) != CHANGEOVER_PROTOCOL) && - (msg_user(msg) != MSG_FRAGMENTER)) { - - /* Try adding message to an existing bundle */ - - if (l_ptr->next_out && - link_bundle_buf(l_ptr, l_ptr->last_out, buf)) { - bearer_resolve_congestion(l_ptr->b_ptr, l_ptr); - return dsz; - } - - /* Try creating a new bundle */ - - if (size <= max_packet * 2 / 3) { - struct sk_buff *bundler = buf_acquire(max_packet); - struct tipc_msg bundler_hdr; - - if (bundler) { - msg_init(&bundler_hdr, MSG_BUNDLER, OPEN_MSG, - TIPC_OK, INT_H_SIZE, l_ptr->addr); - memcpy(bundler->data, (unchar *)&bundler_hdr, - INT_H_SIZE); - skb_trim(bundler, INT_H_SIZE); - link_bundle_buf(l_ptr, bundler, buf); - buf = bundler; - msg = buf_msg(buf); - l_ptr->stats.sent_bundles++; - } - } - } - if (!l_ptr->next_out) - l_ptr->next_out = buf; - link_add_to_outqueue(l_ptr, buf, msg); - bearer_resolve_congestion(l_ptr->b_ptr, l_ptr); - return dsz; -} - -/* - * link_send(): same as link_send_buf(), but the link to use has - * not been selected yet, and the the owner node is not locked - * Called by TIPC internal users, e.g. the name distributor - */ - -int link_send(struct sk_buff *buf, u32 dest, u32 selector) -{ - struct link *l_ptr; - struct node *n_ptr; - int res = -ELINKCONG; - - read_lock_bh(&net_lock); - n_ptr = node_select(dest, selector); - if (n_ptr) { - node_lock(n_ptr); - l_ptr = n_ptr->active_links[selector & 1]; - dbg("link_send: found link %x for dest %x\n", l_ptr, dest); - if (l_ptr) { - res = link_send_buf(l_ptr, buf); - } - node_unlock(n_ptr); - } else { - dbg("Attempt to send msg to unknown node:\n"); - msg_dbg(buf_msg(buf),">>>"); - buf_discard(buf); - } - read_unlock_bh(&net_lock); - return res; -} - -/* - * link_send_buf_fast: Entry for data messages where the - * destination link is known and the header is complete, - * inclusive total message length. Very time critical. - * Link is locked. Returns user data length. - */ - -static inline int link_send_buf_fast(struct link *l_ptr, struct sk_buff *buf, - u32 *used_max_pkt) -{ - struct tipc_msg *msg = buf_msg(buf); - int res = msg_data_sz(msg); - - if (likely(!link_congested(l_ptr))) { - if (likely(msg_size(msg) <= link_max_pkt(l_ptr))) { - if (likely(list_empty(&l_ptr->b_ptr->cong_links))) { - link_add_to_outqueue(l_ptr, buf, msg); - if (likely(bearer_send(l_ptr->b_ptr, buf, - &l_ptr->media_addr))) { - l_ptr->unacked_window = 0; - msg_dbg(msg,"SENT_FAST:"); - return res; - } - dbg("failed sent fast...\n"); - bearer_schedule(l_ptr->b_ptr, l_ptr); - l_ptr->stats.bearer_congs++; - l_ptr->next_out = buf; - return res; - } - } - else - *used_max_pkt = link_max_pkt(l_ptr); - } - return link_send_buf(l_ptr, buf); /* All other cases */ -} - -/* - * tipc_send_buf_fast: Entry for data messages where the - * destination node is known and the header is complete, - * inclusive total message length. - * Returns user data length. - */ -int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) -{ - struct link *l_ptr; - struct node *n_ptr; - int res; - u32 selector = msg_origport(buf_msg(buf)) & 1; - u32 dummy; - - if (destnode == tipc_own_addr) - return port_recv_msg(buf); - - read_lock_bh(&net_lock); - n_ptr = node_select(destnode, selector); - if (likely(n_ptr)) { - node_lock(n_ptr); - l_ptr = n_ptr->active_links[selector]; - dbg("send_fast: buf %x selected %x, destnode = %x\n", - buf, l_ptr, destnode); - if (likely(l_ptr)) { - res = link_send_buf_fast(l_ptr, buf, &dummy); - node_unlock(n_ptr); - read_unlock_bh(&net_lock); - return res; - } - node_unlock(n_ptr); - } - read_unlock_bh(&net_lock); - res = msg_data_sz(buf_msg(buf)); - tipc_reject_msg(buf, TIPC_ERR_NO_NODE); - return res; -} - - -/* - * link_send_sections_fast: Entry for messages where the - * destination processor is known and the header is complete, - * except for total message length. - * Returns user data length or errno. - */ -int link_send_sections_fast(struct port *sender, - struct iovec const *msg_sect, - const u32 num_sect, - u32 destaddr) -{ - struct tipc_msg *hdr = &sender->publ.phdr; - struct link *l_ptr; - struct sk_buff *buf; - struct node *node; - int res; - u32 selector = msg_origport(hdr) & 1; - - assert(destaddr != tipc_own_addr); - -again: - /* - * Try building message using port's max_pkt hint. - * (Must not hold any locks while building message.) - */ - - res = msg_build(hdr, msg_sect, num_sect, sender->max_pkt, - !sender->user_port, &buf); - - read_lock_bh(&net_lock); - node = node_select(destaddr, selector); - if (likely(node)) { - node_lock(node); - l_ptr = node->active_links[selector]; - if (likely(l_ptr)) { - if (likely(buf)) { - res = link_send_buf_fast(l_ptr, buf, - &sender->max_pkt); - if (unlikely(res < 0)) - buf_discard(buf); -exit: - node_unlock(node); - read_unlock_bh(&net_lock); - return res; - } - - /* Exit if build request was invalid */ - - if (unlikely(res < 0)) - goto exit; - - /* Exit if link (or bearer) is congested */ - - if (link_congested(l_ptr) || - !list_empty(&l_ptr->b_ptr->cong_links)) { - res = link_schedule_port(l_ptr, - sender->publ.ref, res); - goto exit; - } - - /* - * Message size exceeds max_pkt hint; update hint, - * then re-try fast path or fragment the message - */ - - sender->max_pkt = link_max_pkt(l_ptr); - node_unlock(node); - read_unlock_bh(&net_lock); - - - if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt) - goto again; - - return link_send_sections_long(sender, msg_sect, - num_sect, destaddr); - } - node_unlock(node); - } - read_unlock_bh(&net_lock); - - /* Couldn't find a link to the destination node */ - - if (buf) - return tipc_reject_msg(buf, TIPC_ERR_NO_NODE); - if (res >= 0) - return port_reject_sections(sender, hdr, msg_sect, num_sect, - TIPC_ERR_NO_NODE); - return res; -} - -/* - * link_send_sections_long(): Entry for long messages where the - * destination node is known and the header is complete, - * inclusive total message length. - * Link and bearer congestion status have been checked to be ok, - * and are ignored if they change. - * - * Note that fragments do not use the full link MTU so that they won't have - * to undergo refragmentation if link changeover causes them to be sent - * over another link with an additional tunnel header added as prefix. - * (Refragmentation will still occur if the other link has a smaller MTU.) - * - * Returns user data length or errno. - */ -static int link_send_sections_long(struct port *sender, - struct iovec const *msg_sect, - u32 num_sect, - u32 destaddr) -{ - struct link *l_ptr; - struct node *node; - struct tipc_msg *hdr = &sender->publ.phdr; - u32 dsz = msg_data_sz(hdr); - u32 max_pkt,fragm_sz,rest; - struct tipc_msg fragm_hdr; - struct sk_buff *buf,*buf_chain,*prev; - u32 fragm_crs,fragm_rest,hsz,sect_rest; - const unchar *sect_crs; - int curr_sect; - u32 fragm_no; - -again: - fragm_no = 1; - max_pkt = sender->max_pkt - INT_H_SIZE; - /* leave room for tunnel header in case of link changeover */ - fragm_sz = max_pkt - INT_H_SIZE; - /* leave room for fragmentation header in each fragment */ - rest = dsz; - fragm_crs = 0; - fragm_rest = 0; - sect_rest = 0; - sect_crs = 0; - curr_sect = -1; - - /* Prepare reusable fragment header: */ - - msg_dbg(hdr, ">FRAGMENTING>"); - msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, - TIPC_OK, INT_H_SIZE, msg_destnode(hdr)); - msg_set_link_selector(&fragm_hdr, sender->publ.ref); - msg_set_size(&fragm_hdr, max_pkt); - msg_set_fragm_no(&fragm_hdr, 1); - - /* Prepare header of first fragment: */ - - buf_chain = buf = buf_acquire(max_pkt); - if (!buf) - return -ENOMEM; - buf->next = NULL; - memcpy(buf->data, (unchar *)&fragm_hdr, INT_H_SIZE); - hsz = msg_hdr_sz(hdr); - memcpy(buf->data + INT_H_SIZE, (unchar *)hdr, hsz); - msg_dbg(buf_msg(buf), ">BUILD>"); - - /* Chop up message: */ - - fragm_crs = INT_H_SIZE + hsz; - fragm_rest = fragm_sz - hsz; - - do { /* For all sections */ - u32 sz; - - if (!sect_rest) { - sect_rest = msg_sect[++curr_sect].iov_len; - sect_crs = (const unchar *)msg_sect[curr_sect].iov_base; - } - - if (sect_rest < fragm_rest) - sz = sect_rest; - else - sz = fragm_rest; - - if (likely(!sender->user_port)) { - if (copy_from_user(buf->data + fragm_crs, sect_crs, sz)) { -error: - for (; buf_chain; buf_chain = buf) { - buf = buf_chain->next; - buf_discard(buf_chain); - } - return -EFAULT; - } - } else - memcpy(buf->data + fragm_crs, sect_crs, sz); - - sect_crs += sz; - sect_rest -= sz; - fragm_crs += sz; - fragm_rest -= sz; - rest -= sz; - - if (!fragm_rest && rest) { - - /* Initiate new fragment: */ - if (rest <= fragm_sz) { - fragm_sz = rest; - msg_set_type(&fragm_hdr,LAST_FRAGMENT); - } else { - msg_set_type(&fragm_hdr, FRAGMENT); - } - msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); - msg_set_fragm_no(&fragm_hdr, ++fragm_no); - prev = buf; - buf = buf_acquire(fragm_sz + INT_H_SIZE); - if (!buf) - goto error; - - buf->next = NULL; - prev->next = buf; - memcpy(buf->data, (unchar *)&fragm_hdr, INT_H_SIZE); - fragm_crs = INT_H_SIZE; - fragm_rest = fragm_sz; - msg_dbg(buf_msg(buf)," >BUILD>"); - } - } - while (rest > 0); - - /* - * Now we have a buffer chain. Select a link and check - * that packet size is still OK - */ - node = node_select(destaddr, sender->publ.ref & 1); - if (likely(node)) { - node_lock(node); - l_ptr = node->active_links[sender->publ.ref & 1]; - if (!l_ptr) { - node_unlock(node); - goto reject; - } - if (link_max_pkt(l_ptr) < max_pkt) { - sender->max_pkt = link_max_pkt(l_ptr); - node_unlock(node); - for (; buf_chain; buf_chain = buf) { - buf = buf_chain->next; - buf_discard(buf_chain); - } - goto again; - } - } else { -reject: - for (; buf_chain; buf_chain = buf) { - buf = buf_chain->next; - buf_discard(buf_chain); - } - return port_reject_sections(sender, hdr, msg_sect, num_sect, - TIPC_ERR_NO_NODE); - } - - /* Append whole chain to send queue: */ - - buf = buf_chain; - l_ptr->long_msg_seq_no = mod(l_ptr->long_msg_seq_no + 1); - if (!l_ptr->next_out) - l_ptr->next_out = buf_chain; - l_ptr->stats.sent_fragmented++; - while (buf) { - struct sk_buff *next = buf->next; - struct tipc_msg *msg = buf_msg(buf); - - l_ptr->stats.sent_fragments++; - msg_set_long_msgno(msg, l_ptr->long_msg_seq_no); - link_add_to_outqueue(l_ptr, buf, msg); - msg_dbg(msg, ">ADD>"); - buf = next; - } - - /* Send it, if possible: */ - - link_push_queue(l_ptr); - node_unlock(node); - return dsz; -} - -/* - * link_push_packet: Push one unsent packet to the media - */ -u32 link_push_packet(struct link *l_ptr) -{ - struct sk_buff *buf = l_ptr->first_out; - u32 r_q_size = l_ptr->retransm_queue_size; - u32 r_q_head = l_ptr->retransm_queue_head; - - /* Step to position where retransmission failed, if any, */ - /* consider that buffers may have been released in meantime */ - - if (r_q_size && buf) { - u32 last = lesser(mod(r_q_head + r_q_size), - link_last_sent(l_ptr)); - u32 first = msg_seqno(buf_msg(buf)); - - while (buf && less(first, r_q_head)) { - first = mod(first + 1); - buf = buf->next; - } - l_ptr->retransm_queue_head = r_q_head = first; - l_ptr->retransm_queue_size = r_q_size = mod(last - first); - } - - /* Continue retransmission now, if there is anything: */ - - if (r_q_size && buf && !skb_cloned(buf)) { - msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); - msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); - if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { - msg_dbg(buf_msg(buf), ">DEF-RETR>"); - l_ptr->retransm_queue_head = mod(++r_q_head); - l_ptr->retransm_queue_size = --r_q_size; - l_ptr->stats.retransmitted++; - return TIPC_OK; - } else { - l_ptr->stats.bearer_congs++; - msg_dbg(buf_msg(buf), "|>DEF-RETR>"); - return PUSH_FAILED; - } - } - - /* Send deferred protocol message, if any: */ - - buf = l_ptr->proto_msg_queue; - if (buf) { - msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); - msg_set_bcast_ack(buf_msg(buf),l_ptr->owner->bclink.last_in); - if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { - msg_dbg(buf_msg(buf), ">DEF-PROT>"); - l_ptr->unacked_window = 0; - buf_discard(buf); - l_ptr->proto_msg_queue = 0; - return TIPC_OK; - } else { - msg_dbg(buf_msg(buf), "|>DEF-PROT>"); - l_ptr->stats.bearer_congs++; - return PUSH_FAILED; - } - } - - /* Send one deferred data message, if send window not full: */ - - buf = l_ptr->next_out; - if (buf) { - struct tipc_msg *msg = buf_msg(buf); - u32 next = msg_seqno(msg); - u32 first = msg_seqno(buf_msg(l_ptr->first_out)); - - if (mod(next - first) < l_ptr->queue_limit[0]) { - msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); - msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); - if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { - if (msg_user(msg) == MSG_BUNDLER) - msg_set_type(msg, CLOSED_MSG); - msg_dbg(msg, ">PUSH-DATA>"); - l_ptr->next_out = buf->next; - return TIPC_OK; - } else { - msg_dbg(msg, "|PUSH-DATA|"); - l_ptr->stats.bearer_congs++; - return PUSH_FAILED; - } - } - } - return PUSH_FINISHED; -} - -/* - * push_queue(): push out the unsent messages of a link where - * congestion has abated. Node is locked - */ -void link_push_queue(struct link *l_ptr) -{ - u32 res; - - if (bearer_congested(l_ptr->b_ptr, l_ptr)) - return; - - do { - res = link_push_packet(l_ptr); - } - while (res == TIPC_OK); - if (res == PUSH_FAILED) - bearer_schedule(l_ptr->b_ptr, l_ptr); -} - -void link_retransmit(struct link *l_ptr, struct sk_buff *buf, - u32 retransmits) -{ - struct tipc_msg *msg; - - dbg("Retransmitting %u in link %x\n", retransmits, l_ptr); - - if (bearer_congested(l_ptr->b_ptr, l_ptr) && buf && !skb_cloned(buf)) { - msg_dbg(buf_msg(buf), ">NO_RETR->BCONG>"); - dbg_print_link(l_ptr, " "); - l_ptr->retransm_queue_head = msg_seqno(buf_msg(buf)); - l_ptr->retransm_queue_size = retransmits; - return; - } - while (retransmits && (buf != l_ptr->next_out) && buf && !skb_cloned(buf)) { - msg = buf_msg(buf); - msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); - msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); - if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { - /* Catch if retransmissions fail repeatedly: */ - if (l_ptr->last_retransmitted == msg_seqno(msg)) { - if (++l_ptr->stale_count > 100) { - msg_print(CONS, buf_msg(buf), ">RETR>"); - info("...Retransmitted %u times\n", - l_ptr->stale_count); - link_print(l_ptr, CONS, "Resetting Link\n");; - link_reset(l_ptr); - break; - } - } else { - l_ptr->stale_count = 0; - } - l_ptr->last_retransmitted = msg_seqno(msg); - - msg_dbg(buf_msg(buf), ">RETR>"); - buf = buf->next; - retransmits--; - l_ptr->stats.retransmitted++; - } else { - bearer_schedule(l_ptr->b_ptr, l_ptr); - l_ptr->stats.bearer_congs++; - l_ptr->retransm_queue_head = msg_seqno(buf_msg(buf)); - l_ptr->retransm_queue_size = retransmits; - return; - } - } - l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; -} - -/* - * link_recv_non_seq: Receive packets which are outside - * the link sequence flow - */ - -static void link_recv_non_seq(struct sk_buff *buf) -{ - struct tipc_msg *msg = buf_msg(buf); - - if (msg_user(msg) == LINK_CONFIG) - disc_recv_msg(buf); - else - bclink_recv_pkt(buf); -} - -/** - * link_insert_deferred_queue - insert deferred messages back into receive chain - */ - -static struct sk_buff *link_insert_deferred_queue(struct link *l_ptr, - struct sk_buff *buf) -{ - u32 seq_no; - - if (l_ptr->oldest_deferred_in == NULL) - return buf; - - seq_no = msg_seqno(buf_msg(l_ptr->oldest_deferred_in)); - if (seq_no == mod(l_ptr->next_in_no)) { - l_ptr->newest_deferred_in->next = buf; - buf = l_ptr->oldest_deferred_in; - l_ptr->oldest_deferred_in = NULL; - l_ptr->deferred_inqueue_sz = 0; - } - return buf; -} - -void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) -{ - read_lock_bh(&net_lock); - while (head) { - struct bearer *b_ptr; - struct node *n_ptr; - struct link *l_ptr; - struct sk_buff *crs; - struct sk_buff *buf = head; - struct tipc_msg *msg = buf_msg(buf); - u32 seq_no = msg_seqno(msg); - u32 ackd = msg_ack(msg); - u32 released = 0; - int type; - - b_ptr = (struct bearer *)tb_ptr; - TIPC_SKB_CB(buf)->handle = b_ptr; - - head = head->next; - if (unlikely(msg_version(msg) != TIPC_VERSION)) - goto cont; -#if 0 - if (msg_user(msg) != LINK_PROTOCOL) -#endif - msg_dbg(msg,"links[b_ptr->identity]; - if (unlikely(!l_ptr)) { - node_unlock(n_ptr); - goto cont; - } - /* - * Release acked messages - */ - if (less(n_ptr->bclink.acked, msg_bcast_ack(msg))) { - if (node_is_up(n_ptr) && n_ptr->bclink.supported) - bclink_acknowledge(n_ptr, msg_bcast_ack(msg)); - } - - crs = l_ptr->first_out; - while ((crs != l_ptr->next_out) && - less_eq(msg_seqno(buf_msg(crs)), ackd)) { - struct sk_buff *next = crs->next; - - buf_discard(crs); - crs = next; - released++; - } - if (released) { - l_ptr->first_out = crs; - l_ptr->out_queue_size -= released; - } - if (unlikely(l_ptr->next_out)) - link_push_queue(l_ptr); - if (unlikely(!list_empty(&l_ptr->waiting_ports))) - link_wakeup_ports(l_ptr, 0); - if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) { - l_ptr->stats.sent_acks++; - link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); - } - -protocol_check: - if (likely(link_working_working(l_ptr))) { - if (likely(seq_no == mod(l_ptr->next_in_no))) { - l_ptr->next_in_no++; - if (unlikely(l_ptr->oldest_deferred_in)) - head = link_insert_deferred_queue(l_ptr, - head); - if (likely(msg_is_dest(msg, tipc_own_addr))) { -deliver: - if (likely(msg_isdata(msg))) { - node_unlock(n_ptr); - port_recv_msg(buf); - continue; - } - switch (msg_user(msg)) { - case MSG_BUNDLER: - l_ptr->stats.recv_bundles++; - l_ptr->stats.recv_bundled += - msg_msgcnt(msg); - node_unlock(n_ptr); - link_recv_bundle(buf); - continue; - case ROUTE_DISTRIBUTOR: - node_unlock(n_ptr); - cluster_recv_routing_table(buf); - continue; - case NAME_DISTRIBUTOR: - node_unlock(n_ptr); - named_recv(buf); - continue; - case CONN_MANAGER: - node_unlock(n_ptr); - port_recv_proto_msg(buf); - continue; - case MSG_FRAGMENTER: - l_ptr->stats.recv_fragments++; - if (link_recv_fragment( - &l_ptr->defragm_buf, - &buf, &msg)) { - l_ptr->stats.recv_fragmented++; - goto deliver; - } - break; - case CHANGEOVER_PROTOCOL: - type = msg_type(msg); - if (link_recv_changeover_msg( - &l_ptr, &buf)) { - msg = buf_msg(buf); - seq_no = msg_seqno(msg); - TIPC_SKB_CB(buf)->handle - = b_ptr; - if (type == ORIGINAL_MSG) - goto deliver; - goto protocol_check; - } - break; - } - } - node_unlock(n_ptr); - net_route_msg(buf); - continue; - } - link_handle_out_of_seq_msg(l_ptr, buf); - head = link_insert_deferred_queue(l_ptr, head); - node_unlock(n_ptr); - continue; - } - - if (msg_user(msg) == LINK_PROTOCOL) { - link_recv_proto_msg(l_ptr, buf); - head = link_insert_deferred_queue(l_ptr, head); - node_unlock(n_ptr); - continue; - } - msg_dbg(msg,"NSEQnext = head; - head = buf; - node_unlock(n_ptr); - continue; - } - node_unlock(n_ptr); -cont: - buf_discard(buf); - } - read_unlock_bh(&net_lock); -} - -/* - * link_defer_buf(): Sort a received out-of-sequence packet - * into the deferred reception queue. - * Returns the increase of the queue length,i.e. 0 or 1 - */ - -u32 link_defer_pkt(struct sk_buff **head, - struct sk_buff **tail, - struct sk_buff *buf) -{ - struct sk_buff *prev = 0; - struct sk_buff *crs = *head; - u32 seq_no = msg_seqno(buf_msg(buf)); - - buf->next = NULL; - - /* Empty queue ? */ - if (*head == NULL) { - *head = *tail = buf; - return 1; - } - - /* Last ? */ - if (less(msg_seqno(buf_msg(*tail)), seq_no)) { - (*tail)->next = buf; - *tail = buf; - return 1; - } - - /* Scan through queue and sort it in */ - do { - struct tipc_msg *msg = buf_msg(crs); - - if (less(seq_no, msg_seqno(msg))) { - buf->next = crs; - if (prev) - prev->next = buf; - else - *head = buf; - return 1; - } - if (seq_no == msg_seqno(msg)) { - break; - } - prev = crs; - crs = crs->next; - } - while (crs); - - /* Message is a duplicate of an existing message */ - - buf_discard(buf); - return 0; -} - -/** - * link_handle_out_of_seq_msg - handle arrival of out-of-sequence packet - */ - -static void link_handle_out_of_seq_msg(struct link *l_ptr, - struct sk_buff *buf) -{ - u32 seq_no = msg_seqno(buf_msg(buf)); - - if (likely(msg_user(buf_msg(buf)) == LINK_PROTOCOL)) { - link_recv_proto_msg(l_ptr, buf); - return; - } - - dbg("rx OOS msg: seq_no %u, expecting %u (%u)\n", - seq_no, mod(l_ptr->next_in_no), l_ptr->next_in_no); - - /* Record OOS packet arrival (force mismatch on next timeout) */ - - l_ptr->checkpoint--; - - /* - * Discard packet if a duplicate; otherwise add it to deferred queue - * and notify peer of gap as per protocol specification - */ - - if (less(seq_no, mod(l_ptr->next_in_no))) { - l_ptr->stats.duplicates++; - buf_discard(buf); - return; - } - - if (link_defer_pkt(&l_ptr->oldest_deferred_in, - &l_ptr->newest_deferred_in, buf)) { - l_ptr->deferred_inqueue_sz++; - l_ptr->stats.deferred_recv++; - if ((l_ptr->deferred_inqueue_sz % 16) == 1) - link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); - } else - l_ptr->stats.duplicates++; -} - -/* - * Send protocol message to the other endpoint. - */ -void link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, - u32 gap, u32 tolerance, u32 priority, u32 ack_mtu) -{ - struct sk_buff *buf = 0; - struct tipc_msg *msg = l_ptr->pmsg; - u32 msg_size = sizeof(l_ptr->proto_msg); - - if (link_blocked(l_ptr)) - return; - msg_set_type(msg, msg_typ); - msg_set_net_plane(msg, l_ptr->b_ptr->net_plane); - msg_set_bcast_ack(msg, mod(l_ptr->owner->bclink.last_in)); - msg_set_last_bcast(msg, bclink_get_last_sent()); - - if (msg_typ == STATE_MSG) { - u32 next_sent = mod(l_ptr->next_out_no); - - if (!link_is_up(l_ptr)) - return; - if (l_ptr->next_out) - next_sent = msg_seqno(buf_msg(l_ptr->next_out)); - msg_set_next_sent(msg, next_sent); - if (l_ptr->oldest_deferred_in) { - u32 rec = msg_seqno(buf_msg(l_ptr->oldest_deferred_in)); - gap = mod(rec - mod(l_ptr->next_in_no)); - } - msg_set_seq_gap(msg, gap); - if (gap) - l_ptr->stats.sent_nacks++; - msg_set_link_tolerance(msg, tolerance); - msg_set_linkprio(msg, priority); - msg_set_max_pkt(msg, ack_mtu); - msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); - msg_set_probe(msg, probe_msg != 0); - if (probe_msg) { - u32 mtu = l_ptr->max_pkt; - - if ((mtu < l_ptr->max_pkt_target) && - link_working_working(l_ptr) && - l_ptr->fsm_msg_cnt) { - msg_size = (mtu + (l_ptr->max_pkt_target - mtu)/2 + 2) & ~3; - if (l_ptr->max_pkt_probes == 10) { - l_ptr->max_pkt_target = (msg_size - 4); - l_ptr->max_pkt_probes = 0; - msg_size = (mtu + (l_ptr->max_pkt_target - mtu)/2 + 2) & ~3; - } - l_ptr->max_pkt_probes++; - } - - l_ptr->stats.sent_probes++; - } - l_ptr->stats.sent_states++; - } else { /* RESET_MSG or ACTIVATE_MSG */ - msg_set_ack(msg, mod(l_ptr->reset_checkpoint - 1)); - msg_set_seq_gap(msg, 0); - msg_set_next_sent(msg, 1); - msg_set_link_tolerance(msg, l_ptr->tolerance); - msg_set_linkprio(msg, l_ptr->priority); - msg_set_max_pkt(msg, l_ptr->max_pkt_target); - } - - if (node_has_redundant_links(l_ptr->owner)) { - msg_set_redundant_link(msg); - } else { - msg_clear_redundant_link(msg); - } - msg_set_linkprio(msg, l_ptr->priority); - - /* Ensure sequence number will not fit : */ - - msg_set_seqno(msg, mod(l_ptr->next_out_no + (0xffff/2))); - - /* Congestion? */ - - if (bearer_congested(l_ptr->b_ptr, l_ptr)) { - if (!l_ptr->proto_msg_queue) { - l_ptr->proto_msg_queue = - buf_acquire(sizeof(l_ptr->proto_msg)); - } - buf = l_ptr->proto_msg_queue; - if (!buf) - return; - memcpy(buf->data, (unchar *)msg, sizeof(l_ptr->proto_msg)); - return; - } - msg_set_timestamp(msg, jiffies_to_msecs(jiffies)); - - /* Message can be sent */ - - msg_dbg(msg, ">>"); - - buf = buf_acquire(msg_size); - if (!buf) - return; - - memcpy(buf->data, (unchar *)msg, sizeof(l_ptr->proto_msg)); - msg_set_size(buf_msg(buf), msg_size); - - if (bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { - l_ptr->unacked_window = 0; - buf_discard(buf); - return; - } - - /* New congestion */ - bearer_schedule(l_ptr->b_ptr, l_ptr); - l_ptr->proto_msg_queue = buf; - l_ptr->stats.bearer_congs++; -} - -/* - * Receive protocol message : - * Note that network plane id propagates through the network, and may - * change at any time. The node with lowest address rules - */ - -static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) -{ - u32 rec_gap = 0; - u32 max_pkt_info; - u32 max_pkt_ack; - u32 msg_tol; - struct tipc_msg *msg = buf_msg(buf); - - dbg("AT(%u):", jiffies_to_msecs(jiffies)); - msg_dbg(msg, "<<"); - if (link_blocked(l_ptr)) - goto exit; - - /* record unnumbered packet arrival (force mismatch on next timeout) */ - - l_ptr->checkpoint--; - - if (l_ptr->b_ptr->net_plane != msg_net_plane(msg)) - if (tipc_own_addr > msg_prevnode(msg)) - l_ptr->b_ptr->net_plane = msg_net_plane(msg); - - l_ptr->owner->permit_changeover = msg_redundant_link(msg); - - switch (msg_type(msg)) { - - case RESET_MSG: - if (!link_working_unknown(l_ptr) && l_ptr->peer_session) { - if (msg_session(msg) == l_ptr->peer_session) { - dbg("Duplicate RESET: %u<->%u\n", - msg_session(msg), l_ptr->peer_session); - break; /* duplicate: ignore */ - } - } - /* fall thru' */ - case ACTIVATE_MSG: - /* Update link settings according other endpoint's values */ - - strcpy((strrchr(l_ptr->name, ':') + 1), (char *)msg_data(msg)); - - if ((msg_tol = msg_link_tolerance(msg)) && - (msg_tol > l_ptr->tolerance)) - link_set_supervision_props(l_ptr, msg_tol); - - if (msg_linkprio(msg) > l_ptr->priority) - l_ptr->priority = msg_linkprio(msg); - - max_pkt_info = msg_max_pkt(msg); - if (max_pkt_info) { - if (max_pkt_info < l_ptr->max_pkt_target) - l_ptr->max_pkt_target = max_pkt_info; - if (l_ptr->max_pkt > l_ptr->max_pkt_target) - l_ptr->max_pkt = l_ptr->max_pkt_target; - } else { - l_ptr->max_pkt = l_ptr->max_pkt_target; - } - l_ptr->owner->bclink.supported = (max_pkt_info != 0); - - link_state_event(l_ptr, msg_type(msg)); - - l_ptr->peer_session = msg_session(msg); - l_ptr->peer_bearer_id = msg_bearer_id(msg); - - /* Synchronize broadcast sequence numbers */ - if (!node_has_redundant_links(l_ptr->owner)) { - l_ptr->owner->bclink.last_in = mod(msg_last_bcast(msg)); - } - break; - case STATE_MSG: - - if ((msg_tol = msg_link_tolerance(msg))) - link_set_supervision_props(l_ptr, msg_tol); - - if (msg_linkprio(msg) && - (msg_linkprio(msg) != l_ptr->priority)) { - warn("Changing prio <%s>: %u->%u\n", - l_ptr->name, l_ptr->priority, msg_linkprio(msg)); - l_ptr->priority = msg_linkprio(msg); - link_reset(l_ptr); /* Enforce change to take effect */ - break; - } - link_state_event(l_ptr, TRAFFIC_MSG_EVT); - l_ptr->stats.recv_states++; - if (link_reset_unknown(l_ptr)) - break; - - if (less_eq(mod(l_ptr->next_in_no), msg_next_sent(msg))) { - rec_gap = mod(msg_next_sent(msg) - - mod(l_ptr->next_in_no)); - } - - max_pkt_ack = msg_max_pkt(msg); - if (max_pkt_ack > l_ptr->max_pkt) { - dbg("Link <%s> updated MTU %u -> %u\n", - l_ptr->name, l_ptr->max_pkt, max_pkt_ack); - l_ptr->max_pkt = max_pkt_ack; - l_ptr->max_pkt_probes = 0; - } - - max_pkt_ack = 0; - if (msg_probe(msg)) { - l_ptr->stats.recv_probes++; - if (msg_size(msg) > sizeof(l_ptr->proto_msg)) { - max_pkt_ack = msg_size(msg); - } - } - - /* Protocol message before retransmits, reduce loss risk */ - - bclink_check_gap(l_ptr->owner, msg_last_bcast(msg)); - - if (rec_gap || (msg_probe(msg))) { - link_send_proto_msg(l_ptr, STATE_MSG, - 0, rec_gap, 0, 0, max_pkt_ack); - } - if (msg_seq_gap(msg)) { - msg_dbg(msg, "With Gap:"); - l_ptr->stats.recv_nacks++; - link_retransmit(l_ptr, l_ptr->first_out, - msg_seq_gap(msg)); - } - break; - default: - msg_dbg(buf_msg(buf), "owner->active_links[selector & 1]; - if (!link_is_up(tunnel)) - return; - msg_set_size(tunnel_hdr, length + INT_H_SIZE); - buf = buf_acquire(length + INT_H_SIZE); - if (!buf) - return; - memcpy(buf->data, (unchar *)tunnel_hdr, INT_H_SIZE); - memcpy(buf->data + INT_H_SIZE, (unchar *)msg, length); - dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane); - msg_dbg(buf_msg(buf), ">SEND>"); - assert(tunnel); - link_send_buf(tunnel, buf); -} - - - -/* - * changeover(): Send whole message queue via the remaining link - * Owner node is locked. - */ - -void link_changeover(struct link *l_ptr) -{ - u32 msgcount = l_ptr->out_queue_size; - struct sk_buff *crs = l_ptr->first_out; - struct link *tunnel = l_ptr->owner->active_links[0]; - int split_bundles = node_has_redundant_links(l_ptr->owner); - struct tipc_msg tunnel_hdr; - - if (!tunnel) - return; - - if (!l_ptr->owner->permit_changeover) - return; - - msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, - ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); - msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); - msg_set_msgcnt(&tunnel_hdr, msgcount); - if (!l_ptr->first_out) { - struct sk_buff *buf; - - assert(!msgcount); - buf = buf_acquire(INT_H_SIZE); - if (buf) { - memcpy(buf->data, (unchar *)&tunnel_hdr, INT_H_SIZE); - msg_set_size(&tunnel_hdr, INT_H_SIZE); - dbg("%c->%c:", l_ptr->b_ptr->net_plane, - tunnel->b_ptr->net_plane); - msg_dbg(&tunnel_hdr, "EMPTY>SEND>"); - link_send_buf(tunnel, buf); - } else { - warn("Memory squeeze; link changeover failed\n"); - } - return; - } - while (crs) { - struct tipc_msg *msg = buf_msg(crs); - - if ((msg_user(msg) == MSG_BUNDLER) && split_bundles) { - u32 msgcount = msg_msgcnt(msg); - struct tipc_msg *m = msg_get_wrapped(msg); - unchar* pos = (unchar*)m; - - while (msgcount--) { - msg_set_seqno(m,msg_seqno(msg)); - link_tunnel(l_ptr, &tunnel_hdr, m, - msg_link_selector(m)); - pos += align(msg_size(m)); - m = (struct tipc_msg *)pos; - } - } else { - link_tunnel(l_ptr, &tunnel_hdr, msg, - msg_link_selector(msg)); - } - crs = crs->next; - } -} - -void link_send_duplicate(struct link *l_ptr, struct link *tunnel) -{ - struct sk_buff *iter; - struct tipc_msg tunnel_hdr; - - msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL, - DUPLICATE_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr); - msg_set_msgcnt(&tunnel_hdr, l_ptr->out_queue_size); - msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id); - iter = l_ptr->first_out; - while (iter) { - struct sk_buff *outbuf; - struct tipc_msg *msg = buf_msg(iter); - u32 length = msg_size(msg); - - if (msg_user(msg) == MSG_BUNDLER) - msg_set_type(msg, CLOSED_MSG); - msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */ - msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); - msg_set_size(&tunnel_hdr, length + INT_H_SIZE); - outbuf = buf_acquire(length + INT_H_SIZE); - if (outbuf == NULL) { - warn("Memory squeeze; buffer duplication failed\n"); - return; - } - memcpy(outbuf->data, (unchar *)&tunnel_hdr, INT_H_SIZE); - memcpy(outbuf->data + INT_H_SIZE, iter->data, length); - dbg("%c->%c:", l_ptr->b_ptr->net_plane, - tunnel->b_ptr->net_plane); - msg_dbg(buf_msg(outbuf), ">SEND>"); - link_send_buf(tunnel, outbuf); - if (!link_is_up(l_ptr)) - return; - iter = iter->next; - } -} - - - -/** - * buf_extract - extracts embedded TIPC message from another message - * @skb: encapsulating message buffer - * @from_pos: offset to extract from - * - * Returns a new message buffer containing an embedded message. The - * encapsulating message itself is left unchanged. - */ - -static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos) -{ - struct tipc_msg *msg = (struct tipc_msg *)(skb->data + from_pos); - u32 size = msg_size(msg); - struct sk_buff *eb; - - eb = buf_acquire(size); - if (eb) - memcpy(eb->data, (unchar *)msg, size); - return eb; -} - -/* - * link_recv_changeover_msg(): Receive tunneled packet sent - * via other link. Node is locked. Return extracted buffer. - */ - -static int link_recv_changeover_msg(struct link **l_ptr, - struct sk_buff **buf) -{ - struct sk_buff *tunnel_buf = *buf; - struct link *dest_link; - struct tipc_msg *msg; - struct tipc_msg *tunnel_msg = buf_msg(tunnel_buf); - u32 msg_typ = msg_type(tunnel_msg); - u32 msg_count = msg_msgcnt(tunnel_msg); - - dest_link = (*l_ptr)->owner->links[msg_bearer_id(tunnel_msg)]; - assert(dest_link != *l_ptr); - if (!dest_link) { - msg_dbg(tunnel_msg, "NOLINK/b_ptr->net_plane, - (*l_ptr)->b_ptr->net_plane); - *l_ptr = dest_link; - msg = msg_get_wrapped(tunnel_msg); - - if (msg_typ == DUPLICATE_MSG) { - if (less(msg_seqno(msg), mod(dest_link->next_in_no))) { - msg_dbg(tunnel_msg, "DROP/exp_msg_count = msg_count; - if (!msg_count) - goto exit; - } else if (dest_link->exp_msg_count == START_CHANGEOVER) { - msg_dbg(tunnel_msg, "BLK/FIRST/exp_msg_count = msg_count; - if (!msg_count) - goto exit; - } - - /* Receive original message */ - - if (dest_link->exp_msg_count == 0) { - msg_dbg(tunnel_msg, "OVERDUE/DROP/exp_msg_count--; - if (less(msg_seqno(msg), dest_link->reset_checkpoint)) { - msg_dbg(tunnel_msg, "DROP/DUPL/data; - u32 rest = insize; - u32 pack_sz = link_max_pkt(l_ptr); - u32 fragm_sz = pack_sz - INT_H_SIZE; - u32 fragm_no = 1; - u32 destaddr = msg_destnode(inmsg); - - if (msg_short(inmsg)) - destaddr = l_ptr->addr; - - if (msg_routed(inmsg)) - msg_set_prevnode(inmsg, tipc_own_addr); - - /* Prepare reusable fragment header: */ - - msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, - TIPC_OK, INT_H_SIZE, destaddr); - msg_set_link_selector(&fragm_hdr, msg_link_selector(inmsg)); - msg_set_long_msgno(&fragm_hdr, mod(l_ptr->long_msg_seq_no++)); - msg_set_fragm_no(&fragm_hdr, fragm_no); - l_ptr->stats.sent_fragmented++; - - /* Chop up message: */ - - while (rest > 0) { - struct sk_buff *fragm; - - if (rest <= fragm_sz) { - fragm_sz = rest; - msg_set_type(&fragm_hdr, LAST_FRAGMENT); - } - fragm = buf_acquire(fragm_sz + INT_H_SIZE); - if (fragm == NULL) { - warn("Memory squeeze; failed to fragment msg\n"); - dsz = -ENOMEM; - goto exit; - } - msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); - memcpy(fragm->data, (unchar *)&fragm_hdr, INT_H_SIZE); - memcpy(fragm->data + INT_H_SIZE, crs, fragm_sz); - - /* Send queued messages first, if any: */ - - l_ptr->stats.sent_fragments++; - link_send_buf(l_ptr, fragm); - if (!link_is_up(l_ptr)) - return dsz; - msg_set_fragm_no(&fragm_hdr, ++fragm_no); - rest -= fragm_sz; - crs += fragm_sz; - msg_set_type(&fragm_hdr, FRAGMENT); - } -exit: - buf_discard(buf); - return dsz; -} - -/* - * A pending message being re-assembled must store certain values - * to handle subsequent fragments correctly. The following functions - * help storing these values in unused, available fields in the - * pending message. This makes dynamic memory allocation unecessary. - */ - -static inline u32 get_long_msg_seqno(struct sk_buff *buf) -{ - return msg_seqno(buf_msg(buf)); -} - -static inline void set_long_msg_seqno(struct sk_buff *buf, u32 seqno) -{ - msg_set_seqno(buf_msg(buf), seqno); -} - -static inline u32 get_fragm_size(struct sk_buff *buf) -{ - return msg_ack(buf_msg(buf)); -} - -static inline void set_fragm_size(struct sk_buff *buf, u32 sz) -{ - msg_set_ack(buf_msg(buf), sz); -} - -static inline u32 get_expected_frags(struct sk_buff *buf) -{ - return msg_bcast_ack(buf_msg(buf)); -} - -static inline void set_expected_frags(struct sk_buff *buf, u32 exp) -{ - msg_set_bcast_ack(buf_msg(buf), exp); -} - -static inline u32 get_timer_cnt(struct sk_buff *buf) -{ - return msg_reroute_cnt(buf_msg(buf)); -} - -static inline void incr_timer_cnt(struct sk_buff *buf) -{ - msg_incr_reroute_cnt(buf_msg(buf)); -} - -/* - * link_recv_fragment(): Called with node lock on. Returns - * the reassembled buffer if message is complete. - */ -int link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, - struct tipc_msg **m) -{ - struct sk_buff *prev = 0; - struct sk_buff *fbuf = *fb; - struct tipc_msg *fragm = buf_msg(fbuf); - struct sk_buff *pbuf = *pending; - u32 long_msg_seq_no = msg_long_msgno(fragm); - - *fb = 0; - msg_dbg(fragm,"FRGnext; - } - - if (!pbuf && (msg_type(fragm) == FIRST_FRAGMENT)) { - struct tipc_msg *imsg = (struct tipc_msg *)msg_data(fragm); - u32 msg_sz = msg_size(imsg); - u32 fragm_sz = msg_data_sz(fragm); - u32 exp_fragm_cnt = msg_sz/fragm_sz + !!(msg_sz % fragm_sz); - u32 max = TIPC_MAX_USER_MSG_SIZE + LONG_H_SIZE; - if (msg_type(imsg) == TIPC_MCAST_MSG) - max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE; - if (msg_size(imsg) > max) { - msg_dbg(fragm,"next = *pending; - *pending = pbuf; - memcpy(pbuf->data, (unchar *)imsg, msg_data_sz(fragm)); - - /* Prepare buffer for subsequent fragments. */ - - set_long_msg_seqno(pbuf, long_msg_seq_no); - set_fragm_size(pbuf,fragm_sz); - set_expected_frags(pbuf,exp_fragm_cnt - 1); - } else { - warn("Memory squeeze; got no defragmenting buffer\n"); - } - buf_discard(fbuf); - return 0; - } else if (pbuf && (msg_type(fragm) != FIRST_FRAGMENT)) { - u32 dsz = msg_data_sz(fragm); - u32 fsz = get_fragm_size(pbuf); - u32 crs = ((msg_fragm_no(fragm) - 1) * fsz); - u32 exp_frags = get_expected_frags(pbuf) - 1; - memcpy(pbuf->data + crs, msg_data(fragm), dsz); - buf_discard(fbuf); - - /* Is message complete? */ - - if (exp_frags == 0) { - if (prev) - prev->next = pbuf->next; - else - *pending = pbuf->next; - msg_reset_reroute_cnt(buf_msg(pbuf)); - *fb = pbuf; - *m = buf_msg(pbuf); - return 1; - } - set_expected_frags(pbuf,exp_frags); - return 0; - } - dbg(" Discarding orphan fragment %x\n",fbuf); - msg_dbg(fragm,"ORPHAN:"); - dbg("Pending long buffers:\n"); - dbg_print_buf_chain(*pending); - buf_discard(fbuf); - return 0; -} - -/** - * link_check_defragm_bufs - flush stale incoming message fragments - * @l_ptr: pointer to link - */ - -static void link_check_defragm_bufs(struct link *l_ptr) -{ - struct sk_buff *prev = 0; - struct sk_buff *next = 0; - struct sk_buff *buf = l_ptr->defragm_buf; - - if (!buf) - return; - if (!link_working_working(l_ptr)) - return; - while (buf) { - u32 cnt = get_timer_cnt(buf); - - next = buf->next; - if (cnt < 4) { - incr_timer_cnt(buf); - prev = buf; - } else { - dbg(" Discarding incomplete long buffer\n"); - msg_dbg(buf_msg(buf), "LONG:"); - dbg_print_link(l_ptr, "curr:"); - dbg("Pending long buffers:\n"); - dbg_print_buf_chain(l_ptr->defragm_buf); - if (prev) - prev->next = buf->next; - else - l_ptr->defragm_buf = buf->next; - buf_discard(buf); - } - buf = next; - } -} - - - -static void link_set_supervision_props(struct link *l_ptr, u32 tolerance) -{ - l_ptr->tolerance = tolerance; - l_ptr->continuity_interval = - ((tolerance / 4) > 500) ? 500 : tolerance / 4; - l_ptr->abort_limit = tolerance / (l_ptr->continuity_interval / 4); -} - - -void link_set_queue_limits(struct link *l_ptr, u32 window) -{ - /* Data messages from this node, inclusive FIRST_FRAGM */ - l_ptr->queue_limit[DATA_LOW] = window; - l_ptr->queue_limit[DATA_MEDIUM] = (window / 3) * 4; - l_ptr->queue_limit[DATA_HIGH] = (window / 3) * 5; - l_ptr->queue_limit[DATA_CRITICAL] = (window / 3) * 6; - /* Transiting data messages,inclusive FIRST_FRAGM */ - l_ptr->queue_limit[DATA_LOW + 4] = 300; - l_ptr->queue_limit[DATA_MEDIUM + 4] = 600; - l_ptr->queue_limit[DATA_HIGH + 4] = 900; - l_ptr->queue_limit[DATA_CRITICAL + 4] = 1200; - l_ptr->queue_limit[CONN_MANAGER] = 1200; - l_ptr->queue_limit[ROUTE_DISTRIBUTOR] = 1200; - l_ptr->queue_limit[CHANGEOVER_PROTOCOL] = 2500; - l_ptr->queue_limit[NAME_DISTRIBUTOR] = 3000; - /* FRAGMENT and LAST_FRAGMENT packets */ - l_ptr->queue_limit[MSG_FRAGMENTER] = 4000; -} - -/** - * link_find_link - locate link by name - * @name - ptr to link name string - * @node - ptr to area to be filled with ptr to associated node - * - * Caller must hold 'net_lock' to ensure node and bearer are not deleted; - * this also prevents link deletion. - * - * Returns pointer to link (or 0 if invalid link name). - */ - -static struct link *link_find_link(const char *name, struct node **node) -{ - struct link_name link_name_parts; - struct bearer *b_ptr; - struct link *l_ptr; - - if (!link_name_validate(name, &link_name_parts)) - return 0; - - b_ptr = bearer_find_interface(link_name_parts.if_local); - if (!b_ptr) - return 0; - - *node = node_find(link_name_parts.addr_peer); - if (!*node) - return 0; - - l_ptr = (*node)->links[b_ptr->identity]; - if (!l_ptr || strcmp(l_ptr->name, name)) - return 0; - - return l_ptr; -} - -struct sk_buff *link_cmd_config(const void *req_tlv_area, int req_tlv_space, - u16 cmd) -{ - struct tipc_link_config *args; - u32 new_value; - struct link *l_ptr; - struct node *node; - int res; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_CONFIG)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - args = (struct tipc_link_config *)TLV_DATA(req_tlv_area); - new_value = ntohl(args->value); - - if (!strcmp(args->name, bc_link_name)) { - if ((cmd == TIPC_CMD_SET_LINK_WINDOW) && - (bclink_set_queue_limits(new_value) == 0)) - return cfg_reply_none(); - return cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED - " (cannot change setting on broadcast link)"); - } - - read_lock_bh(&net_lock); - l_ptr = link_find_link(args->name, &node); - if (!l_ptr) { - read_unlock_bh(&net_lock); - return cfg_reply_error_string("link not found"); - } - - node_lock(node); - res = -EINVAL; - switch (cmd) { - case TIPC_CMD_SET_LINK_TOL: - if ((new_value >= TIPC_MIN_LINK_TOL) && - (new_value <= TIPC_MAX_LINK_TOL)) { - link_set_supervision_props(l_ptr, new_value); - link_send_proto_msg(l_ptr, STATE_MSG, - 0, 0, new_value, 0, 0); - res = TIPC_OK; - } - break; - case TIPC_CMD_SET_LINK_PRI: - if (new_value < TIPC_NUM_LINK_PRI) { - l_ptr->priority = new_value; - link_send_proto_msg(l_ptr, STATE_MSG, - 0, 0, 0, new_value, 0); - res = TIPC_OK; - } - break; - case TIPC_CMD_SET_LINK_WINDOW: - if ((new_value >= TIPC_MIN_LINK_WIN) && - (new_value <= TIPC_MAX_LINK_WIN)) { - link_set_queue_limits(l_ptr, new_value); - res = TIPC_OK; - } - break; - } - node_unlock(node); - - read_unlock_bh(&net_lock); - if (res) - return cfg_reply_error_string("cannot change link setting"); - - return cfg_reply_none(); -} - -/** - * link_reset_statistics - reset link statistics - * @l_ptr: pointer to link - */ - -static void link_reset_statistics(struct link *l_ptr) -{ - memset(&l_ptr->stats, 0, sizeof(l_ptr->stats)); - l_ptr->stats.sent_info = l_ptr->next_out_no; - l_ptr->stats.recv_info = l_ptr->next_in_no; -} - -struct sk_buff *link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space) -{ - char *link_name; - struct link *l_ptr; - struct node *node; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - link_name = (char *)TLV_DATA(req_tlv_area); - if (!strcmp(link_name, bc_link_name)) { - if (bclink_reset_stats()) - return cfg_reply_error_string("link not found"); - return cfg_reply_none(); - } - - read_lock_bh(&net_lock); - l_ptr = link_find_link(link_name, &node); - if (!l_ptr) { - read_unlock_bh(&net_lock); - return cfg_reply_error_string("link not found"); - } - - node_lock(node); - link_reset_statistics(l_ptr); - node_unlock(node); - read_unlock_bh(&net_lock); - return cfg_reply_none(); -} - -/** - * percent - convert count to a percentage of total (rounding up or down) - */ - -static u32 percent(u32 count, u32 total) -{ - return (count * 100 + (total / 2)) / total; -} - -/** - * link_stats - print link statistics - * @name: link name - * @buf: print buffer area - * @buf_size: size of print buffer area - * - * Returns length of print buffer data string (or 0 if error) - */ - -static int link_stats(const char *name, char *buf, const u32 buf_size) -{ - struct print_buf pb; - struct link *l_ptr; - struct node *node; - char *status; - u32 profile_total = 0; - - if (!strcmp(name, bc_link_name)) - return bclink_stats(buf, buf_size); - - printbuf_init(&pb, buf, buf_size); - - read_lock_bh(&net_lock); - l_ptr = link_find_link(name, &node); - if (!l_ptr) { - read_unlock_bh(&net_lock); - return 0; - } - node_lock(node); - - if (link_is_active(l_ptr)) - status = "ACTIVE"; - else if (link_is_up(l_ptr)) - status = "STANDBY"; - else - status = "DEFUNCT"; - tipc_printf(&pb, "Link <%s>\n" - " %s MTU:%u Priority:%u Tolerance:%u ms" - " Window:%u packets\n", - l_ptr->name, status, link_max_pkt(l_ptr), - l_ptr->priority, l_ptr->tolerance, l_ptr->queue_limit[0]); - tipc_printf(&pb, " RX packets:%u fragments:%u/%u bundles:%u/%u\n", - l_ptr->next_in_no - l_ptr->stats.recv_info, - l_ptr->stats.recv_fragments, - l_ptr->stats.recv_fragmented, - l_ptr->stats.recv_bundles, - l_ptr->stats.recv_bundled); - tipc_printf(&pb, " TX packets:%u fragments:%u/%u bundles:%u/%u\n", - l_ptr->next_out_no - l_ptr->stats.sent_info, - l_ptr->stats.sent_fragments, - l_ptr->stats.sent_fragmented, - l_ptr->stats.sent_bundles, - l_ptr->stats.sent_bundled); - profile_total = l_ptr->stats.msg_length_counts; - if (!profile_total) - profile_total = 1; - tipc_printf(&pb, " TX profile sample:%u packets average:%u octets\n" - " 0-64:%u%% -256:%u%% -1024:%u%% -4096:%u%% " - "-16354:%u%% -32768:%u%% -66000:%u%%\n", - l_ptr->stats.msg_length_counts, - l_ptr->stats.msg_lengths_total / profile_total, - percent(l_ptr->stats.msg_length_profile[0], profile_total), - percent(l_ptr->stats.msg_length_profile[1], profile_total), - percent(l_ptr->stats.msg_length_profile[2], profile_total), - percent(l_ptr->stats.msg_length_profile[3], profile_total), - percent(l_ptr->stats.msg_length_profile[4], profile_total), - percent(l_ptr->stats.msg_length_profile[5], profile_total), - percent(l_ptr->stats.msg_length_profile[6], profile_total)); - tipc_printf(&pb, " RX states:%u probes:%u naks:%u defs:%u dups:%u\n", - l_ptr->stats.recv_states, - l_ptr->stats.recv_probes, - l_ptr->stats.recv_nacks, - l_ptr->stats.deferred_recv, - l_ptr->stats.duplicates); - tipc_printf(&pb, " TX states:%u probes:%u naks:%u acks:%u dups:%u\n", - l_ptr->stats.sent_states, - l_ptr->stats.sent_probes, - l_ptr->stats.sent_nacks, - l_ptr->stats.sent_acks, - l_ptr->stats.retransmitted); - tipc_printf(&pb, " Congestion bearer:%u link:%u Send queue max:%u avg:%u\n", - l_ptr->stats.bearer_congs, - l_ptr->stats.link_congs, - l_ptr->stats.max_queue_sz, - l_ptr->stats.queue_sz_counts - ? (l_ptr->stats.accu_queue_sz / l_ptr->stats.queue_sz_counts) - : 0); - - node_unlock(node); - read_unlock_bh(&net_lock); - return printbuf_validate(&pb); -} - -#define MAX_LINK_STATS_INFO 2000 - -struct sk_buff *link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space) -{ - struct sk_buff *buf; - struct tlv_desc *rep_tlv; - int str_len; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - buf = cfg_reply_alloc(TLV_SPACE(MAX_LINK_STATS_INFO)); - if (!buf) - return NULL; - - rep_tlv = (struct tlv_desc *)buf->data; - - str_len = link_stats((char *)TLV_DATA(req_tlv_area), - (char *)TLV_DATA(rep_tlv), MAX_LINK_STATS_INFO); - if (!str_len) { - buf_discard(buf); - return cfg_reply_error_string("link not found"); - } - - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - -#if 0 -int link_control(const char *name, u32 op, u32 val) -{ - int res = -EINVAL; - struct link *l_ptr; - u32 bearer_id; - struct node * node; - u32 a; - - a = link_name2addr(name, &bearer_id); - read_lock_bh(&net_lock); - node = node_find(a); - if (node) { - node_lock(node); - l_ptr = node->links[bearer_id]; - if (l_ptr) { - if (op == TIPC_REMOVE_LINK) { - struct bearer *b_ptr = l_ptr->b_ptr; - spin_lock_bh(&b_ptr->publ.lock); - link_delete(l_ptr); - spin_unlock_bh(&b_ptr->publ.lock); - } - if (op == TIPC_CMD_BLOCK_LINK) { - link_reset(l_ptr); - l_ptr->blocked = 1; - } - if (op == TIPC_CMD_UNBLOCK_LINK) { - l_ptr->blocked = 0; - } - res = TIPC_OK; - } - node_unlock(node); - } - read_unlock_bh(&net_lock); - return res; -} -#endif - -/** - * link_get_max_pkt - get maximum packet size to use when sending to destination - * @dest: network address of destination node - * @selector: used to select from set of active links - * - * If no active link can be found, uses default maximum packet size. - */ - -u32 link_get_max_pkt(u32 dest, u32 selector) -{ - struct node *n_ptr; - struct link *l_ptr; - u32 res = MAX_PKT_DEFAULT; - - if (dest == tipc_own_addr) - return MAX_MSG_SIZE; - - read_lock_bh(&net_lock); - n_ptr = node_select(dest, selector); - if (n_ptr) { - node_lock(n_ptr); - l_ptr = n_ptr->active_links[selector & 1]; - if (l_ptr) - res = link_max_pkt(l_ptr); - node_unlock(n_ptr); - } - read_unlock_bh(&net_lock); - return res; -} - -#if 0 -static void link_dump_rec_queue(struct link *l_ptr) -{ - struct sk_buff *crs; - - if (!l_ptr->oldest_deferred_in) { - info("Reception queue empty\n"); - return; - } - info("Contents of Reception queue:\n"); - crs = l_ptr->oldest_deferred_in; - while (crs) { - if (crs->data == (void *)0x0000a3a3) { - info("buffer %x invalid\n", crs); - return; - } - msg_dbg(buf_msg(crs), "In rec queue: \n"); - crs = crs->next; - } -} -#endif - -static void link_dump_send_queue(struct link *l_ptr) -{ - if (l_ptr->next_out) { - info("\nContents of unsent queue:\n"); - dbg_print_buf_chain(l_ptr->next_out); - } - info("\nContents of send queue:\n"); - if (l_ptr->first_out) { - dbg_print_buf_chain(l_ptr->first_out); - } - info("Empty send queue\n"); -} - -static void link_print(struct link *l_ptr, struct print_buf *buf, - const char *str) -{ - tipc_printf(buf, str); - if (link_reset_reset(l_ptr) || link_reset_unknown(l_ptr)) - return; - tipc_printf(buf, "Link %x<%s>:", - l_ptr->addr, l_ptr->b_ptr->publ.name); - tipc_printf(buf, ": NXO(%u):", mod(l_ptr->next_out_no)); - tipc_printf(buf, "NXI(%u):", mod(l_ptr->next_in_no)); - tipc_printf(buf, "SQUE"); - if (l_ptr->first_out) { - tipc_printf(buf, "[%u..", msg_seqno(buf_msg(l_ptr->first_out))); - if (l_ptr->next_out) - tipc_printf(buf, "%u..", - msg_seqno(buf_msg(l_ptr->next_out))); - tipc_printf(buf, "%u]", - msg_seqno(buf_msg - (l_ptr->last_out)), l_ptr->out_queue_size); - if ((mod(msg_seqno(buf_msg(l_ptr->last_out)) - - msg_seqno(buf_msg(l_ptr->first_out))) - != (l_ptr->out_queue_size - 1)) - || (l_ptr->last_out->next != 0)) { - tipc_printf(buf, "\nSend queue inconsistency\n"); - tipc_printf(buf, "first_out= %x ", l_ptr->first_out); - tipc_printf(buf, "next_out= %x ", l_ptr->next_out); - tipc_printf(buf, "last_out= %x ", l_ptr->last_out); - link_dump_send_queue(l_ptr); - } - } else - tipc_printf(buf, "[]"); - tipc_printf(buf, "SQSIZ(%u)", l_ptr->out_queue_size); - if (l_ptr->oldest_deferred_in) { - u32 o = msg_seqno(buf_msg(l_ptr->oldest_deferred_in)); - u32 n = msg_seqno(buf_msg(l_ptr->newest_deferred_in)); - tipc_printf(buf, ":RQUE[%u..%u]", o, n); - if (l_ptr->deferred_inqueue_sz != mod((n + 1) - o)) { - tipc_printf(buf, ":RQSIZ(%u)", - l_ptr->deferred_inqueue_sz); - } - } - if (link_working_unknown(l_ptr)) - tipc_printf(buf, ":WU"); - if (link_reset_reset(l_ptr)) - tipc_printf(buf, ":RR"); - if (link_reset_unknown(l_ptr)) - tipc_printf(buf, ":RU"); - if (link_working_working(l_ptr)) - tipc_printf(buf, ":WW"); - tipc_printf(buf, "\n"); -} - diff --git a/trunk/net/tipc/link.h b/trunk/net/tipc/link.h deleted file mode 100644 index c2553f073757..000000000000 --- a/trunk/net/tipc/link.h +++ /dev/null @@ -1,296 +0,0 @@ -/* - * net/tipc/link.h: Include file for TIPC link code - * - * Copyright (c) 1995-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_LINK_H -#define _TIPC_LINK_H - -#include "dbg.h" -#include "msg.h" -#include "bearer.h" -#include "node.h" - -#define PUSH_FAILED 1 -#define PUSH_FINISHED 2 - -/* - * Link states - */ - -#define WORKING_WORKING 560810u -#define WORKING_UNKNOWN 560811u -#define RESET_UNKNOWN 560812u -#define RESET_RESET 560813u - -/* - * Starting value for maximum packet size negotiation on unicast links - * (unless bearer MTU is less) - */ - -#define MAX_PKT_DEFAULT 1500 - -/** - * struct link - TIPC link data structure - * @addr: network address of link's peer node - * @name: link name character string - * @media_addr: media address to use when sending messages over link - * @timer: link timer - * @owner: pointer to peer node - * @link_list: adjacent links in bearer's list of links - * @started: indicates if link has been started - * @checkpoint: reference point for triggering link continuity checking - * @peer_session: link session # being used by peer end of link - * @peer_bearer_id: bearer id used by link's peer endpoint - * @b_ptr: pointer to bearer used by link - * @tolerance: minimum link continuity loss needed to reset link [in ms] - * @continuity_interval: link continuity testing interval [in ms] - * @abort_limit: # of unacknowledged continuity probes needed to reset link - * @state: current state of link FSM - * @blocked: indicates if link has been administratively blocked - * @fsm_msg_cnt: # of protocol messages link FSM has sent in current state - * @proto_msg: template for control messages generated by link - * @pmsg: convenience pointer to "proto_msg" field - * @priority: current link priority - * @queue_limit: outbound message queue congestion thresholds (indexed by user) - * @exp_msg_count: # of tunnelled messages expected during link changeover - * @reset_checkpoint: seq # of last acknowledged message at time of link reset - * @max_pkt: current maximum packet size for this link - * @max_pkt_target: desired maximum packet size for this link - * @max_pkt_probes: # of probes based on current (max_pkt, max_pkt_target) - * @out_queue_size: # of messages in outbound message queue - * @first_out: ptr to first outbound message in queue - * @last_out: ptr to last outbound message in queue - * @next_out_no: next sequence number to use for outbound messages - * @last_retransmitted: sequence number of most recently retransmitted message - * @stale_count: # of identical retransmit requests made by peer - * @next_in_no: next sequence number to expect for inbound messages - * @deferred_inqueue_sz: # of messages in inbound message queue - * @oldest_deferred_in: ptr to first inbound message in queue - * @newest_deferred_in: ptr to last inbound message in queue - * @unacked_window: # of inbound messages rx'd without ack'ing back to peer - * @proto_msg_queue: ptr to (single) outbound control message - * @retransm_queue_size: number of messages to retransmit - * @retransm_queue_head: sequence number of first message to retransmit - * @next_out: ptr to first unsent outbound message in queue - * @waiting_ports: linked list of ports waiting for link congestion to abate - * @long_msg_seq_no: next identifier to use for outbound fragmented messages - * @defragm_buf: list of partially reassembled inbound message fragments - * @stats: collects statistics regarding link activity - * @print_buf: print buffer used to log link activity - */ - -struct link { - u32 addr; - char name[TIPC_MAX_LINK_NAME]; - struct tipc_media_addr media_addr; - struct timer_list timer; - struct node *owner; - struct list_head link_list; - - /* Management and link supervision data */ - int started; - u32 checkpoint; - u32 peer_session; - u32 peer_bearer_id; - struct bearer *b_ptr; - u32 tolerance; - u32 continuity_interval; - u32 abort_limit; - int state; - int blocked; - u32 fsm_msg_cnt; - struct { - unchar hdr[INT_H_SIZE]; - unchar body[TIPC_MAX_IF_NAME]; - } proto_msg; - struct tipc_msg *pmsg; - u32 priority; - u32 queue_limit[15]; /* queue_limit[0]==window limit */ - - /* Changeover */ - u32 exp_msg_count; - u32 reset_checkpoint; - - /* Max packet negotiation */ - u32 max_pkt; - u32 max_pkt_target; - u32 max_pkt_probes; - - /* Sending */ - u32 out_queue_size; - struct sk_buff *first_out; - struct sk_buff *last_out; - u32 next_out_no; - u32 last_retransmitted; - u32 stale_count; - - /* Reception */ - u32 next_in_no; - u32 deferred_inqueue_sz; - struct sk_buff *oldest_deferred_in; - struct sk_buff *newest_deferred_in; - u32 unacked_window; - - /* Congestion handling */ - struct sk_buff *proto_msg_queue; - u32 retransm_queue_size; - u32 retransm_queue_head; - struct sk_buff *next_out; - struct list_head waiting_ports; - - /* Fragmentation/defragmentation */ - u32 long_msg_seq_no; - struct sk_buff *defragm_buf; - - /* Statistics */ - struct { - u32 sent_info; /* used in counting # sent packets */ - u32 recv_info; /* used in counting # recv'd packets */ - u32 sent_states; - u32 recv_states; - u32 sent_probes; - u32 recv_probes; - u32 sent_nacks; - u32 recv_nacks; - u32 sent_acks; - u32 sent_bundled; - u32 sent_bundles; - u32 recv_bundled; - u32 recv_bundles; - u32 retransmitted; - u32 sent_fragmented; - u32 sent_fragments; - u32 recv_fragmented; - u32 recv_fragments; - u32 link_congs; /* # port sends blocked by congestion */ - u32 bearer_congs; - u32 deferred_recv; - u32 duplicates; - - /* for statistical profiling of send queue size */ - - u32 max_queue_sz; - u32 accu_queue_sz; - u32 queue_sz_counts; - - /* for statistical profiling of message lengths */ - - u32 msg_length_counts; - u32 msg_lengths_total; - u32 msg_length_profile[7]; -#if 0 - u32 sent_tunneled; - u32 recv_tunneled; -#endif - } stats; - - struct print_buf print_buf; -}; - -struct port; - -struct link *link_create(struct bearer *b_ptr, const u32 peer, - const struct tipc_media_addr *media_addr); -void link_delete(struct link *l_ptr); -void link_changeover(struct link *l_ptr); -void link_send_duplicate(struct link *l_ptr, struct link *dest); -void link_reset_fragments(struct link *l_ptr); -int link_is_up(struct link *l_ptr); -int link_is_active(struct link *l_ptr); -void link_start(struct link *l_ptr); -u32 link_push_packet(struct link *l_ptr); -void link_stop(struct link *l_ptr); -struct sk_buff *link_cmd_config(const void *req_tlv_area, int req_tlv_space, u16 cmd); -struct sk_buff *link_cmd_show_stats(const void *req_tlv_area, int req_tlv_space); -struct sk_buff *link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_space); -void link_reset(struct link *l_ptr); -int link_send(struct sk_buff *buf, u32 dest, u32 selector); -int link_send_buf(struct link *l_ptr, struct sk_buff *buf); -u32 link_get_max_pkt(u32 dest,u32 selector); -int link_send_sections_fast(struct port* sender, - struct iovec const *msg_sect, - const u32 num_sect, - u32 destnode); - -int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf); -void link_tunnel(struct link *l_ptr, struct tipc_msg *tnl_hdr, - struct tipc_msg *msg, u32 selector); -void link_recv_bundle(struct sk_buff *buf); -int link_recv_fragment(struct sk_buff **pending, - struct sk_buff **fb, - struct tipc_msg **msg); -void link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int prob, u32 gap, - u32 tolerance, u32 priority, u32 acked_mtu); -void link_push_queue(struct link *l_ptr); -u32 link_defer_pkt(struct sk_buff **head, struct sk_buff **tail, - struct sk_buff *buf); -void link_wakeup_ports(struct link *l_ptr, int all); -void link_set_queue_limits(struct link *l_ptr, u32 window); -void link_retransmit(struct link *l_ptr, struct sk_buff *start, u32 retransmits); - -/* - * Link sequence number manipulation routines (uses modulo 2**16 arithmetic) - */ - -static inline u32 mod(u32 x) -{ - return x & 0xffffu; -} - -static inline int between(u32 lower, u32 upper, u32 n) -{ - if ((lower < n) && (n < upper)) - return 1; - if ((upper < lower) && ((n > lower) || (n < upper))) - return 1; - return 0; -} - -static inline int less_eq(u32 left, u32 right) -{ - return (mod(right - left) < 32768u); -} - -static inline int less(u32 left, u32 right) -{ - return (less_eq(left, right) && (mod(right) != mod(left))); -} - -static inline u32 lesser(u32 left, u32 right) -{ - return less_eq(left, right) ? left : right; -} - -#endif diff --git a/trunk/net/tipc/msg.c b/trunk/net/tipc/msg.c deleted file mode 100644 index 03dbc55cb04c..000000000000 --- a/trunk/net/tipc/msg.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * net/tipc/msg.c: TIPC message header routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "addr.h" -#include "dbg.h" -#include "msg.h" -#include "bearer.h" - - -void msg_set_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) -{ - memcpy(&((int *)m)[5], a, sizeof(*a)); -} - -void msg_get_media_addr(struct tipc_msg *m, struct tipc_media_addr *a) -{ - memcpy(a, &((int*)m)[5], sizeof(*a)); -} - - -void msg_print(struct print_buf *buf, struct tipc_msg *msg, const char *str) -{ - u32 usr = msg_user(msg); - tipc_printf(buf, str); - - switch (usr) { - case MSG_BUNDLER: - tipc_printf(buf, "BNDL::"); - tipc_printf(buf, "MSGS(%u):", msg_msgcnt(msg)); - break; - case BCAST_PROTOCOL: - tipc_printf(buf, "BCASTP::"); - break; - case MSG_FRAGMENTER: - tipc_printf(buf, "FRAGM::"); - switch (msg_type(msg)) { - case FIRST_FRAGMENT: - tipc_printf(buf, "FIRST:"); - break; - case FRAGMENT: - tipc_printf(buf, "BODY:"); - break; - case LAST_FRAGMENT: - tipc_printf(buf, "LAST:"); - break; - default: - tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); - - } - tipc_printf(buf, "NO(%u/%u):",msg_long_msgno(msg), - msg_fragm_no(msg)); - break; - case DATA_LOW: - case DATA_MEDIUM: - case DATA_HIGH: - case DATA_CRITICAL: - tipc_printf(buf, "DAT%u:", msg_user(msg)); - if (msg_short(msg)) { - tipc_printf(buf, "CON:"); - break; - } - switch (msg_type(msg)) { - case TIPC_CONN_MSG: - tipc_printf(buf, "CON:"); - break; - case TIPC_MCAST_MSG: - tipc_printf(buf, "MCST:"); - break; - case TIPC_NAMED_MSG: - tipc_printf(buf, "NAM:"); - break; - case TIPC_DIRECT_MSG: - tipc_printf(buf, "DIR:"); - break; - default: - tipc_printf(buf, "UNKNOWN TYPE %u",msg_type(msg)); - } - if (msg_routed(msg) && !msg_non_seq(msg)) - tipc_printf(buf, "ROUT:"); - if (msg_reroute_cnt(msg)) - tipc_printf(buf, "REROUTED(%u):", - msg_reroute_cnt(msg)); - break; - case NAME_DISTRIBUTOR: - tipc_printf(buf, "NMD::"); - switch (msg_type(msg)) { - case PUBLICATION: - tipc_printf(buf, "PUBL(%u):", (msg_size(msg) - msg_hdr_sz(msg)) / 20); /* Items */ - break; - case WITHDRAWAL: - tipc_printf(buf, "WDRW:"); - break; - default: - tipc_printf(buf, "UNKNOWN:%x",msg_type(msg)); - } - if (msg_routed(msg)) - tipc_printf(buf, "ROUT:"); - if (msg_reroute_cnt(msg)) - tipc_printf(buf, "REROUTED(%u):", - msg_reroute_cnt(msg)); - break; - case CONN_MANAGER: - tipc_printf(buf, "CONN_MNG:"); - switch (msg_type(msg)) { - case CONN_PROBE: - tipc_printf(buf, "PROBE:"); - break; - case CONN_PROBE_REPLY: - tipc_printf(buf, "PROBE_REPLY:"); - break; - case CONN_ACK: - tipc_printf(buf, "CONN_ACK:"); - tipc_printf(buf, "ACK(%u):",msg_msgcnt(msg)); - break; - default: - tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); - } - if (msg_routed(msg)) - tipc_printf(buf, "ROUT:"); - if (msg_reroute_cnt(msg)) - tipc_printf(buf, "REROUTED(%u):",msg_reroute_cnt(msg)); - break; - case LINK_PROTOCOL: - tipc_printf(buf, "PROT:TIM(%u):",msg_timestamp(msg)); - switch (msg_type(msg)) { - case STATE_MSG: - tipc_printf(buf, "STATE:"); - tipc_printf(buf, "%s:",msg_probe(msg) ? "PRB" :""); - tipc_printf(buf, "NXS(%u):",msg_next_sent(msg)); - tipc_printf(buf, "GAP(%u):",msg_seq_gap(msg)); - tipc_printf(buf, "LSTBC(%u):",msg_last_bcast(msg)); - break; - case RESET_MSG: - tipc_printf(buf, "RESET:"); - if (msg_size(msg) != msg_hdr_sz(msg)) - tipc_printf(buf, "BEAR:%s:",msg_data(msg)); - break; - case ACTIVATE_MSG: - tipc_printf(buf, "ACTIVATE:"); - break; - default: - tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); - } - tipc_printf(buf, "PLANE(%c):",msg_net_plane(msg)); - tipc_printf(buf, "SESS(%u):",msg_session(msg)); - break; - case CHANGEOVER_PROTOCOL: - tipc_printf(buf, "TUNL:"); - switch (msg_type(msg)) { - case DUPLICATE_MSG: - tipc_printf(buf, "DUPL:"); - break; - case ORIGINAL_MSG: - tipc_printf(buf, "ORIG:"); - tipc_printf(buf, "EXP(%u)",msg_msgcnt(msg)); - break; - default: - tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); - } - break; - case ROUTE_DISTRIBUTOR: - tipc_printf(buf, "ROUTING_MNG:"); - switch (msg_type(msg)) { - case EXT_ROUTING_TABLE: - tipc_printf(buf, "EXT_TBL:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); - break; - case LOCAL_ROUTING_TABLE: - tipc_printf(buf, "LOCAL_TBL:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); - break; - case SLAVE_ROUTING_TABLE: - tipc_printf(buf, "DP_TBL:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); - break; - case ROUTE_ADDITION: - tipc_printf(buf, "ADD:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); - break; - case ROUTE_REMOVAL: - tipc_printf(buf, "REMOVE:"); - tipc_printf(buf, "TO:%x:",msg_remote_node(msg)); - break; - default: - tipc_printf(buf, "UNKNOWN TYPE:%x",msg_type(msg)); - } - break; - case LINK_CONFIG: - tipc_printf(buf, "CFG:"); - switch (msg_type(msg)) { - case DSC_REQ_MSG: - tipc_printf(buf, "DSC_REQ:"); - break; - case DSC_RESP_MSG: - tipc_printf(buf, "DSC_RESP:"); - break; - default: - tipc_printf(buf, "UNKNOWN TYPE:%x:",msg_type(msg)); - break; - } - break; - default: - tipc_printf(buf, "UNKNOWN USER:"); - } - - switch (usr) { - case CONN_MANAGER: - case NAME_DISTRIBUTOR: - case DATA_LOW: - case DATA_MEDIUM: - case DATA_HIGH: - case DATA_CRITICAL: - if (msg_short(msg)) - break; /* No error */ - switch (msg_errcode(msg)) { - case TIPC_OK: - break; - case TIPC_ERR_NO_NAME: - tipc_printf(buf, "NO_NAME:"); - break; - case TIPC_ERR_NO_PORT: - tipc_printf(buf, "NO_PORT:"); - break; - case TIPC_ERR_NO_NODE: - tipc_printf(buf, "NO_PROC:"); - break; - case TIPC_ERR_OVERLOAD: - tipc_printf(buf, "OVERLOAD:"); - break; - case TIPC_CONN_SHUTDOWN: - tipc_printf(buf, "SHUTDOWN:"); - break; - default: - tipc_printf(buf, "UNKNOWN ERROR(%x):", - msg_errcode(msg)); - } - default:{} - } - - tipc_printf(buf, "HZ(%u):", msg_hdr_sz(msg)); - tipc_printf(buf, "SZ(%u):", msg_size(msg)); - tipc_printf(buf, "SQNO(%u):", msg_seqno(msg)); - - if (msg_non_seq(msg)) - tipc_printf(buf, "NOSEQ:"); - else { - tipc_printf(buf, "ACK(%u):", msg_ack(msg)); - } - tipc_printf(buf, "BACK(%u):", msg_bcast_ack(msg)); - tipc_printf(buf, "PRND(%x)", msg_prevnode(msg)); - - if (msg_isdata(msg)) { - if (msg_named(msg)) { - tipc_printf(buf, "NTYP(%u):", msg_nametype(msg)); - tipc_printf(buf, "NINST(%u)", msg_nameinst(msg)); - } - } - - if ((usr != LINK_PROTOCOL) && (usr != LINK_CONFIG) && - (usr != MSG_BUNDLER)) { - if (!msg_short(msg)) { - tipc_printf(buf, ":ORIG(%x:%u):", - msg_orignode(msg), msg_origport(msg)); - tipc_printf(buf, ":DEST(%x:%u):", - msg_destnode(msg), msg_destport(msg)); - } else { - tipc_printf(buf, ":OPRT(%u):", msg_origport(msg)); - tipc_printf(buf, ":DPRT(%u):", msg_destport(msg)); - } - if (msg_routed(msg) && !msg_non_seq(msg)) - tipc_printf(buf, ":TSEQN(%u)", msg_transp_seqno(msg)); - } - if (msg_user(msg) == NAME_DISTRIBUTOR) { - tipc_printf(buf, ":ONOD(%x):", msg_orignode(msg)); - tipc_printf(buf, ":DNOD(%x):", msg_destnode(msg)); - if (msg_routed(msg)) { - tipc_printf(buf, ":CSEQN(%u)", msg_transp_seqno(msg)); - } - } - - if (msg_user(msg) == LINK_CONFIG) { - u32* raw = (u32*)msg; - struct tipc_media_addr* orig = (struct tipc_media_addr*)&raw[5]; - tipc_printf(buf, ":REQL(%u):", msg_req_links(msg)); - tipc_printf(buf, ":DDOM(%x):", msg_dest_domain(msg)); - tipc_printf(buf, ":NETID(%u):", msg_bc_netid(msg)); - media_addr_printf(buf, orig); - } - if (msg_user(msg) == BCAST_PROTOCOL) { - tipc_printf(buf, "BCNACK:AFTER(%u):", msg_bcgap_after(msg)); - tipc_printf(buf, "TO(%u):", msg_bcgap_to(msg)); - } - tipc_printf(buf, "\n"); - if ((usr == CHANGEOVER_PROTOCOL) && (msg_msgcnt(msg))) { - msg_print(buf,msg_get_wrapped(msg)," /"); - } - if ((usr == MSG_FRAGMENTER) && (msg_type(msg) == FIRST_FRAGMENT)) { - msg_print(buf,msg_get_wrapped(msg)," /"); - } -} diff --git a/trunk/net/tipc/msg.h b/trunk/net/tipc/msg.h deleted file mode 100644 index 662c81862a0c..000000000000 --- a/trunk/net/tipc/msg.h +++ /dev/null @@ -1,818 +0,0 @@ -/* - * net/tipc/msg.h: Include file for TIPC message header routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_MSG_H -#define _TIPC_MSG_H - -#include - -#define TIPC_VERSION 2 -#define DATA_LOW TIPC_LOW_IMPORTANCE -#define DATA_MEDIUM TIPC_MEDIUM_IMPORTANCE -#define DATA_HIGH TIPC_HIGH_IMPORTANCE -#define DATA_CRITICAL TIPC_CRITICAL_IMPORTANCE -#define SHORT_H_SIZE 24 /* Connected,in cluster */ -#define DIR_MSG_H_SIZE 32 /* Directly addressed messages */ -#define CONN_MSG_H_SIZE 36 /* Routed connected msgs*/ -#define LONG_H_SIZE 40 /* Named Messages */ -#define MCAST_H_SIZE 44 /* Multicast messages */ -#define MAX_H_SIZE 60 /* Inclusive full options */ -#define MAX_MSG_SIZE (MAX_H_SIZE + TIPC_MAX_USER_MSG_SIZE) -#define LINK_CONFIG 13 - - -/* - TIPC user data message header format, version 2 - - - Fundamental definitions available to privileged TIPC users - are located in tipc_msg.h. - - Remaining definitions available to TIPC internal users appear below. -*/ - - -static inline void msg_set_word(struct tipc_msg *m, u32 w, u32 val) -{ - m->hdr[w] = htonl(val); -} - -static inline void msg_set_bits(struct tipc_msg *m, u32 w, - u32 pos, u32 mask, u32 val) -{ - u32 word = msg_word(m,w) & ~(mask << pos); - msg_set_word(m, w, (word |= (val << pos))); -} - -/* - * Word 0 - */ - -static inline u32 msg_version(struct tipc_msg *m) -{ - return msg_bits(m, 0, 29, 7); -} - -static inline void msg_set_version(struct tipc_msg *m) -{ - msg_set_bits(m, 0, 29, 0xf, TIPC_VERSION); -} - -static inline u32 msg_user(struct tipc_msg *m) -{ - return msg_bits(m, 0, 25, 0xf); -} - -static inline u32 msg_isdata(struct tipc_msg *m) -{ - return (msg_user(m) <= DATA_CRITICAL); -} - -static inline void msg_set_user(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 0, 25, 0xf, n); -} - -static inline void msg_set_importance(struct tipc_msg *m, u32 i) -{ - msg_set_user(m, i); -} - -static inline void msg_set_hdr_sz(struct tipc_msg *m,u32 n) -{ - msg_set_bits(m, 0, 21, 0xf, n>>2); -} - -static inline int msg_non_seq(struct tipc_msg *m) -{ - return msg_bits(m, 0, 20, 1); -} - -static inline void msg_set_non_seq(struct tipc_msg *m) -{ - msg_set_bits(m, 0, 20, 1, 1); -} - -static inline int msg_dest_droppable(struct tipc_msg *m) -{ - return msg_bits(m, 0, 19, 1); -} - -static inline void msg_set_dest_droppable(struct tipc_msg *m, u32 d) -{ - msg_set_bits(m, 0, 19, 1, d); -} - -static inline int msg_src_droppable(struct tipc_msg *m) -{ - return msg_bits(m, 0, 18, 1); -} - -static inline void msg_set_src_droppable(struct tipc_msg *m, u32 d) -{ - msg_set_bits(m, 0, 18, 1, d); -} - -static inline void msg_set_size(struct tipc_msg *m, u32 sz) -{ - m->hdr[0] = htonl((msg_word(m, 0) & ~0x1ffff) | sz); -} - - -/* - * Word 1 - */ - -static inline void msg_set_type(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 1, 29, 0x7, n); -} - -static inline void msg_set_errcode(struct tipc_msg *m, u32 err) -{ - msg_set_bits(m, 1, 25, 0xf, err); -} - -static inline u32 msg_reroute_cnt(struct tipc_msg *m) -{ - return msg_bits(m, 1, 21, 0xf); -} - -static inline void msg_incr_reroute_cnt(struct tipc_msg *m) -{ - msg_set_bits(m, 1, 21, 0xf, msg_reroute_cnt(m) + 1); -} - -static inline void msg_reset_reroute_cnt(struct tipc_msg *m) -{ - msg_set_bits(m, 1, 21, 0xf, 0); -} - -static inline u32 msg_lookup_scope(struct tipc_msg *m) -{ - return msg_bits(m, 1, 19, 0x3); -} - -static inline void msg_set_lookup_scope(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 1, 19, 0x3, n); -} - -static inline void msg_set_options(struct tipc_msg *m, const char *opt, u32 sz) -{ - u32 hsz = msg_hdr_sz(m); - char *to = (char *)&m->hdr[hsz/4]; - - if ((hsz < DIR_MSG_H_SIZE) || ((hsz + sz) > MAX_H_SIZE)) - return; - msg_set_bits(m, 1, 16, 0x7, (hsz - 28)/4); - msg_set_hdr_sz(m, hsz + sz); - memcpy(to, opt, sz); -} - -static inline u32 msg_bcast_ack(struct tipc_msg *m) -{ - return msg_bits(m, 1, 0, 0xffff); -} - -static inline void msg_set_bcast_ack(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 1, 0, 0xffff, n); -} - - -/* - * Word 2 - */ - -static inline u32 msg_ack(struct tipc_msg *m) -{ - return msg_bits(m, 2, 16, 0xffff); -} - -static inline void msg_set_ack(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 2, 16, 0xffff, n); -} - -static inline u32 msg_seqno(struct tipc_msg *m) -{ - return msg_bits(m, 2, 0, 0xffff); -} - -static inline void msg_set_seqno(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 2, 0, 0xffff, n); -} - - -/* - * Words 3-10 - */ - - -static inline void msg_set_prevnode(struct tipc_msg *m, u32 a) -{ - msg_set_word(m, 3, a); -} - -static inline void msg_set_origport(struct tipc_msg *m, u32 p) -{ - msg_set_word(m, 4, p); -} - -static inline void msg_set_destport(struct tipc_msg *m, u32 p) -{ - msg_set_word(m, 5, p); -} - -static inline void msg_set_mc_netid(struct tipc_msg *m, u32 p) -{ - msg_set_word(m, 5, p); -} - -static inline void msg_set_orignode(struct tipc_msg *m, u32 a) -{ - msg_set_word(m, 6, a); -} - -static inline void msg_set_destnode(struct tipc_msg *m, u32 a) -{ - msg_set_word(m, 7, a); -} - -static inline int msg_is_dest(struct tipc_msg *m, u32 d) -{ - return(msg_short(m) || (msg_destnode(m) == d)); -} - -static inline u32 msg_routed(struct tipc_msg *m) -{ - if (likely(msg_short(m))) - return 0; - return(msg_destnode(m) ^ msg_orignode(m)) >> 11; -} - -static inline void msg_set_nametype(struct tipc_msg *m, u32 n) -{ - msg_set_word(m, 8, n); -} - -static inline u32 msg_transp_seqno(struct tipc_msg *m) -{ - return msg_word(m, 8); -} - -static inline void msg_set_timestamp(struct tipc_msg *m, u32 n) -{ - msg_set_word(m, 8, n); -} - -static inline u32 msg_timestamp(struct tipc_msg *m) -{ - return msg_word(m, 8); -} - -static inline void msg_set_transp_seqno(struct tipc_msg *m, u32 n) -{ - msg_set_word(m, 8, n); -} - -static inline void msg_set_namelower(struct tipc_msg *m, u32 n) -{ - msg_set_word(m, 9, n); -} - -static inline void msg_set_nameinst(struct tipc_msg *m, u32 n) -{ - msg_set_namelower(m, n); -} - -static inline void msg_set_nameupper(struct tipc_msg *m, u32 n) -{ - msg_set_word(m, 10, n); -} - -static inline struct tipc_msg *msg_get_wrapped(struct tipc_msg *m) -{ - return (struct tipc_msg *)msg_data(m); -} - -static inline void msg_expand(struct tipc_msg *m, u32 destnode) -{ - if (!msg_short(m)) - return; - msg_set_hdr_sz(m, LONG_H_SIZE); - msg_set_orignode(m, msg_prevnode(m)); - msg_set_destnode(m, destnode); - memset(&m->hdr[8], 0, 12); -} - - - -/* - TIPC internal message header format, version 2 - - 1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w0:|vers |msg usr|hdr sz |n|resrv| packet size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w1:|m typ|rsv=0| sequence gap | broadcast ack no | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w2:| link level ack no/bc_gap_from | seq no / bcast_gap_to | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w3:| previous node | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w4:| next sent broadcast/fragm no | next sent pkt/ fragm msg no | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w5:| session no |rsv=0|r|berid|link prio|netpl|p| - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w6:| originating node | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w7:| destination node | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w8:| transport sequence number | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - w9:| msg count / bcast tag | link tolerance | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - \ \ - / User Specific Data / - \ \ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - NB: CONN_MANAGER use data message format. LINK_CONFIG has own format. -*/ - -/* - * Internal users - */ - -#define BCAST_PROTOCOL 5 -#define MSG_BUNDLER 6 -#define LINK_PROTOCOL 7 -#define CONN_MANAGER 8 -#define ROUTE_DISTRIBUTOR 9 -#define CHANGEOVER_PROTOCOL 10 -#define NAME_DISTRIBUTOR 11 -#define MSG_FRAGMENTER 12 -#define LINK_CONFIG 13 -#define INT_H_SIZE 40 -#define DSC_H_SIZE 40 - -/* - * Connection management protocol messages - */ - -#define CONN_PROBE 0 -#define CONN_PROBE_REPLY 1 -#define CONN_ACK 2 - -/* - * Name distributor messages - */ - -#define PUBLICATION 0 -#define WITHDRAWAL 1 - - -/* - * Word 1 - */ - -static inline u32 msg_seq_gap(struct tipc_msg *m) -{ - return msg_bits(m, 1, 16, 0xff); -} - -static inline void msg_set_seq_gap(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 1, 16, 0xff, n); -} - -static inline u32 msg_req_links(struct tipc_msg *m) -{ - return msg_bits(m, 1, 16, 0xfff); -} - -static inline void msg_set_req_links(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 1, 16, 0xfff, n); -} - - -/* - * Word 2 - */ - -static inline u32 msg_dest_domain(struct tipc_msg *m) -{ - return msg_word(m, 2); -} - -static inline void msg_set_dest_domain(struct tipc_msg *m, u32 n) -{ - msg_set_word(m, 2, n); -} - -static inline u32 msg_bcgap_after(struct tipc_msg *m) -{ - return msg_bits(m, 2, 16, 0xffff); -} - -static inline void msg_set_bcgap_after(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 2, 16, 0xffff, n); -} - -static inline u32 msg_bcgap_to(struct tipc_msg *m) -{ - return msg_bits(m, 2, 0, 0xffff); -} - -static inline void msg_set_bcgap_to(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 2, 0, 0xffff, n); -} - - -/* - * Word 4 - */ - -static inline u32 msg_last_bcast(struct tipc_msg *m) -{ - return msg_bits(m, 4, 16, 0xffff); -} - -static inline void msg_set_last_bcast(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 4, 16, 0xffff, n); -} - - -static inline u32 msg_fragm_no(struct tipc_msg *m) -{ - return msg_bits(m, 4, 16, 0xffff); -} - -static inline void msg_set_fragm_no(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 4, 16, 0xffff, n); -} - - -static inline u32 msg_next_sent(struct tipc_msg *m) -{ - return msg_bits(m, 4, 0, 0xffff); -} - -static inline void msg_set_next_sent(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 4, 0, 0xffff, n); -} - - -static inline u32 msg_long_msgno(struct tipc_msg *m) -{ - return msg_bits(m, 4, 0, 0xffff); -} - -static inline void msg_set_long_msgno(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 4, 0, 0xffff, n); -} - -static inline u32 msg_bc_netid(struct tipc_msg *m) -{ - return msg_word(m, 4); -} - -static inline void msg_set_bc_netid(struct tipc_msg *m, u32 id) -{ - msg_set_word(m, 4, id); -} - -static inline u32 msg_link_selector(struct tipc_msg *m) -{ - return msg_bits(m, 4, 0, 1); -} - -static inline void msg_set_link_selector(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 4, 0, 1, (n & 1)); -} - -/* - * Word 5 - */ - -static inline u32 msg_session(struct tipc_msg *m) -{ - return msg_bits(m, 5, 16, 0xffff); -} - -static inline void msg_set_session(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 5, 16, 0xffff, n); -} - -static inline u32 msg_probe(struct tipc_msg *m) -{ - return msg_bits(m, 5, 0, 1); -} - -static inline void msg_set_probe(struct tipc_msg *m, u32 val) -{ - msg_set_bits(m, 5, 0, 1, (val & 1)); -} - -static inline char msg_net_plane(struct tipc_msg *m) -{ - return msg_bits(m, 5, 1, 7) + 'A'; -} - -static inline void msg_set_net_plane(struct tipc_msg *m, char n) -{ - msg_set_bits(m, 5, 1, 7, (n - 'A')); -} - -static inline u32 msg_linkprio(struct tipc_msg *m) -{ - return msg_bits(m, 5, 4, 0x1f); -} - -static inline void msg_set_linkprio(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 5, 4, 0x1f, n); -} - -static inline u32 msg_bearer_id(struct tipc_msg *m) -{ - return msg_bits(m, 5, 9, 0x7); -} - -static inline void msg_set_bearer_id(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 5, 9, 0x7, n); -} - -static inline u32 msg_redundant_link(struct tipc_msg *m) -{ - return msg_bits(m, 5, 12, 0x1); -} - -static inline void msg_set_redundant_link(struct tipc_msg *m) -{ - msg_set_bits(m, 5, 12, 0x1, 1); -} - -static inline void msg_clear_redundant_link(struct tipc_msg *m) -{ - msg_set_bits(m, 5, 12, 0x1, 0); -} - - -/* - * Word 9 - */ - -static inline u32 msg_msgcnt(struct tipc_msg *m) -{ - return msg_bits(m, 9, 16, 0xffff); -} - -static inline void msg_set_msgcnt(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 9, 16, 0xffff, n); -} - -static inline u32 msg_bcast_tag(struct tipc_msg *m) -{ - return msg_bits(m, 9, 16, 0xffff); -} - -static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 9, 16, 0xffff, n); -} - -static inline u32 msg_max_pkt(struct tipc_msg *m) -{ - return (msg_bits(m, 9, 16, 0xffff) * 4); -} - -static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 9, 16, 0xffff, (n / 4)); -} - -static inline u32 msg_link_tolerance(struct tipc_msg *m) -{ - return msg_bits(m, 9, 0, 0xffff); -} - -static inline void msg_set_link_tolerance(struct tipc_msg *m, u32 n) -{ - msg_set_bits(m, 9, 0, 0xffff, n); -} - -/* - * Routing table message data - */ - - -static inline u32 msg_remote_node(struct tipc_msg *m) -{ - return msg_word(m, msg_hdr_sz(m)/4); -} - -static inline void msg_set_remote_node(struct tipc_msg *m, u32 a) -{ - msg_set_word(m, msg_hdr_sz(m)/4, a); -} - -static inline int msg_dataoctet(struct tipc_msg *m, u32 pos) -{ - return(msg_data(m)[pos + 4] != 0); -} - -static inline void msg_set_dataoctet(struct tipc_msg *m, u32 pos) -{ - msg_data(m)[pos + 4] = 1; -} - -/* - * Segmentation message types - */ - -#define FIRST_FRAGMENT 0 -#define FRAGMENT 1 -#define LAST_FRAGMENT 2 - -/* - * Link management protocol message types - */ - -#define STATE_MSG 0 -#define RESET_MSG 1 -#define ACTIVATE_MSG 2 - -/* - * Changeover tunnel message types - */ -#define DUPLICATE_MSG 0 -#define ORIGINAL_MSG 1 - -/* - * Routing table message types - */ -#define EXT_ROUTING_TABLE 0 -#define LOCAL_ROUTING_TABLE 1 -#define SLAVE_ROUTING_TABLE 2 -#define ROUTE_ADDITION 3 -#define ROUTE_REMOVAL 4 - -/* - * Config protocol message types - */ - -#define DSC_REQ_MSG 0 -#define DSC_RESP_MSG 1 - -static inline u32 msg_tot_importance(struct tipc_msg *m) -{ - if (likely(msg_isdata(m))) { - if (likely(msg_orignode(m) == tipc_own_addr)) - return msg_importance(m); - return msg_importance(m) + 4; - } - if ((msg_user(m) == MSG_FRAGMENTER) && - (msg_type(m) == FIRST_FRAGMENT)) - return msg_importance(msg_get_wrapped(m)); - return msg_importance(m); -} - - -static inline void msg_init(struct tipc_msg *m, u32 user, u32 type, - u32 err, u32 hsize, u32 destnode) -{ - memset(m, 0, hsize); - msg_set_version(m); - msg_set_user(m, user); - msg_set_hdr_sz(m, hsize); - msg_set_size(m, hsize); - msg_set_prevnode(m, tipc_own_addr); - msg_set_type(m, type); - msg_set_errcode(m, err); - if (!msg_short(m)) { - msg_set_orignode(m, tipc_own_addr); - msg_set_destnode(m, destnode); - } -} - -/** - * msg_calc_data_size - determine total data size for message - */ - -static inline int msg_calc_data_size(struct iovec const *msg_sect, u32 num_sect) -{ - int dsz = 0; - int i; - - for (i = 0; i < num_sect; i++) - dsz += msg_sect[i].iov_len; - return dsz; -} - -/** - * msg_build - create message using specified header and data - * - * Note: Caller must not hold any locks in case copy_from_user() is interrupted! - * - * Returns message data size or errno - */ - -static inline int msg_build(struct tipc_msg *hdr, - struct iovec const *msg_sect, u32 num_sect, - int max_size, int usrmem, struct sk_buff** buf) -{ - int dsz, sz, hsz, pos, res, cnt; - - dsz = msg_calc_data_size(msg_sect, num_sect); - if (unlikely(dsz > TIPC_MAX_USER_MSG_SIZE)) { - *buf = NULL; - return -EINVAL; - } - - pos = hsz = msg_hdr_sz(hdr); - sz = hsz + dsz; - msg_set_size(hdr, sz); - if (unlikely(sz > max_size)) { - *buf = NULL; - return dsz; - } - - *buf = buf_acquire(sz); - if (!(*buf)) - return -ENOMEM; - memcpy((*buf)->data, (unchar *)hdr, hsz); - for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) { - if (likely(usrmem)) - res = !copy_from_user((*buf)->data + pos, - msg_sect[cnt].iov_base, - msg_sect[cnt].iov_len); - else - memcpy((*buf)->data + pos, msg_sect[cnt].iov_base, - msg_sect[cnt].iov_len); - pos += msg_sect[cnt].iov_len; - } - if (likely(res)) - return dsz; - - buf_discard(*buf); - *buf = NULL; - return -EFAULT; -} - - -struct tipc_media_addr; - -extern void msg_set_media_addr(struct tipc_msg *m, - struct tipc_media_addr *a); - -extern void msg_get_media_addr(struct tipc_msg *m, - struct tipc_media_addr *a); - - -#endif diff --git a/trunk/net/tipc/name_distr.c b/trunk/net/tipc/name_distr.c deleted file mode 100644 index 41cbaf1a4a73..000000000000 --- a/trunk/net/tipc/name_distr.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * net/tipc/name_distr.c: TIPC name distribution code - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "cluster.h" -#include "dbg.h" -#include "link.h" -#include "msg.h" -#include "name_distr.h" - -#undef DBG_OUTPUT -#define DBG_OUTPUT NULL - -#define ITEM_SIZE sizeof(struct distr_item) - -/** - * struct distr_item - publication info distributed to other nodes - * @type: name sequence type - * @lower: name sequence lower bound - * @upper: name sequence upper bound - * @ref: publishing port reference - * @key: publication key - * - * ===> All fields are stored in network byte order. <=== - * - * First 3 fields identify (name or) name sequence being published. - * Reference field uniquely identifies port that published name sequence. - * Key field uniquely identifies publication, in the event a port has - * multiple publications of the same name sequence. - * - * Note: There is no field that identifies the publishing node because it is - * the same for all items contained within a publication message. - */ - -struct distr_item { - u32 type; - u32 lower; - u32 upper; - u32 ref; - u32 key; -}; - -/** - * List of externally visible publications by this node -- - * that is, all publications having scope > TIPC_NODE_SCOPE. - */ - -static LIST_HEAD(publ_root); -static u32 publ_cnt = 0; - -/** - * publ_to_item - add publication info to a publication message - */ - -static void publ_to_item(struct distr_item *i, struct publication *p) -{ - i->type = htonl(p->type); - i->lower = htonl(p->lower); - i->upper = htonl(p->upper); - i->ref = htonl(p->ref); - i->key = htonl(p->key); - dbg("publ_to_item: %u, %u, %u\n", p->type, p->lower, p->upper); -} - -/** - * named_prepare_buf - allocate & initialize a publication message - */ - -static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) -{ - struct sk_buff *buf = buf_acquire(LONG_H_SIZE + size); - struct tipc_msg *msg; - - if (buf != NULL) { - msg = buf_msg(buf); - msg_init(msg, NAME_DISTRIBUTOR, type, TIPC_OK, - LONG_H_SIZE, dest); - msg_set_size(msg, LONG_H_SIZE + size); - } - return buf; -} - -/** - * named_publish - tell other nodes about a new publication by this node - */ - -void named_publish(struct publication *publ) -{ - struct sk_buff *buf; - struct distr_item *item; - - list_add(&publ->local_list, &publ_root); - publ_cnt++; - - buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0); - if (!buf) { - warn("Memory squeeze; failed to distribute publication\n"); - return; - } - - item = (struct distr_item *)msg_data(buf_msg(buf)); - publ_to_item(item, publ); - dbg("named_withdraw: broadcasting publish msg\n"); - cluster_broadcast(buf); -} - -/** - * named_withdraw - tell other nodes about a withdrawn publication by this node - */ - -void named_withdraw(struct publication *publ) -{ - struct sk_buff *buf; - struct distr_item *item; - - list_del(&publ->local_list); - publ_cnt--; - - buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0); - if (!buf) { - warn("Memory squeeze; failed to distribute withdrawal\n"); - return; - } - - item = (struct distr_item *)msg_data(buf_msg(buf)); - publ_to_item(item, publ); - dbg("named_withdraw: broadcasting withdraw msg\n"); - cluster_broadcast(buf); -} - -/** - * named_node_up - tell specified node about all publications by this node - */ - -void named_node_up(unsigned long node) -{ - struct publication *publ; - struct distr_item *item = 0; - struct sk_buff *buf = 0; - u32 left = 0; - u32 rest; - u32 max_item_buf; - - assert(in_own_cluster(node)); - read_lock_bh(&nametbl_lock); - max_item_buf = TIPC_MAX_USER_MSG_SIZE / ITEM_SIZE; - max_item_buf *= ITEM_SIZE; - rest = publ_cnt * ITEM_SIZE; - - list_for_each_entry(publ, &publ_root, local_list) { - if (!buf) { - left = (rest <= max_item_buf) ? rest : max_item_buf; - rest -= left; - buf = named_prepare_buf(PUBLICATION, left, node); - if (buf == NULL) { - warn("Memory Squeeze; could not send publication\n"); - goto exit; - } - item = (struct distr_item *)msg_data(buf_msg(buf)); - } - publ_to_item(item, publ); - item++; - left -= ITEM_SIZE; - if (!left) { - msg_set_link_selector(buf_msg(buf), node); - dbg("named_node_up: sending publish msg to " - "<%u.%u.%u>\n", tipc_zone(node), - tipc_cluster(node), tipc_node(node)); - link_send(buf, node, node); - buf = 0; - } - } -exit: - read_unlock_bh(&nametbl_lock); -} - -/** - * node_is_down - remove publication associated with a failed node - * - * Invoked for each publication issued by a newly failed node. - * Removes publication structure from name table & deletes it. - * In rare cases the link may have come back up again when this - * function is called, and we have two items representing the same - * publication. Nudge this item's key to distinguish it from the other. - * (Note: Publication's node subscription is already unsubscribed.) - */ - -static void node_is_down(struct publication *publ) -{ - struct publication *p; - write_lock_bh(&nametbl_lock); - dbg("node_is_down: withdrawing %u, %u, %u\n", - publ->type, publ->lower, publ->upper); - publ->key += 1222345; - p = nametbl_remove_publ(publ->type, publ->lower, - publ->node, publ->ref, publ->key); - assert(p == publ); - write_unlock_bh(&nametbl_lock); - if (publ) - kfree(publ); -} - -/** - * named_recv - process name table update message sent by another node - */ - -void named_recv(struct sk_buff *buf) -{ - struct publication *publ; - struct tipc_msg *msg = buf_msg(buf); - struct distr_item *item = (struct distr_item *)msg_data(msg); - u32 count = msg_data_sz(msg) / ITEM_SIZE; - - write_lock_bh(&nametbl_lock); - while (count--) { - if (msg_type(msg) == PUBLICATION) { - dbg("named_recv: got publication for %u, %u, %u\n", - ntohl(item->type), ntohl(item->lower), - ntohl(item->upper)); - publ = nametbl_insert_publ(ntohl(item->type), - ntohl(item->lower), - ntohl(item->upper), - TIPC_CLUSTER_SCOPE, - msg_orignode(msg), - ntohl(item->ref), - ntohl(item->key)); - if (publ) { - nodesub_subscribe(&publ->subscr, - msg_orignode(msg), - publ, - (net_ev_handler)node_is_down); - } - } else if (msg_type(msg) == WITHDRAWAL) { - dbg("named_recv: got withdrawl for %u, %u, %u\n", - ntohl(item->type), ntohl(item->lower), - ntohl(item->upper)); - publ = nametbl_remove_publ(ntohl(item->type), - ntohl(item->lower), - msg_orignode(msg), - ntohl(item->ref), - ntohl(item->key)); - - if (publ) { - nodesub_unsubscribe(&publ->subscr); - kfree(publ); - } - } else { - warn("named_recv: unknown msg\n"); - } - item++; - } - write_unlock_bh(&nametbl_lock); - buf_discard(buf); -} - -/** - * named_reinit - re-initialize local publication list - * - * This routine is called whenever TIPC networking is (re)enabled. - * All existing publications by this node that have "cluster" or "zone" scope - * are updated to reflect the node's current network address. - * (If the node's address is unchanged, the update loop terminates immediately.) - */ - -void named_reinit(void) -{ - struct publication *publ; - - write_lock_bh(&nametbl_lock); - list_for_each_entry(publ, &publ_root, local_list) { - if (publ->node == tipc_own_addr) - break; - publ->node = tipc_own_addr; - } - write_unlock_bh(&nametbl_lock); -} diff --git a/trunk/net/tipc/name_distr.h b/trunk/net/tipc/name_distr.h deleted file mode 100644 index a04bdeac84ea..000000000000 --- a/trunk/net/tipc/name_distr.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * net/tipc/name_distr.h: Include file for TIPC name distribution code - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_NAME_DISTR_H -#define _TIPC_NAME_DISTR_H - -#include "name_table.h" - -void named_publish(struct publication *publ); -void named_withdraw(struct publication *publ); -void named_node_up(unsigned long node); -void named_recv(struct sk_buff *buf); -void named_reinit(void); - -#endif diff --git a/trunk/net/tipc/name_table.c b/trunk/net/tipc/name_table.c deleted file mode 100644 index 972c83eb83b4..000000000000 --- a/trunk/net/tipc/name_table.c +++ /dev/null @@ -1,1079 +0,0 @@ -/* - * net/tipc/name_table.c: TIPC name table code - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "config.h" -#include "dbg.h" -#include "name_table.h" -#include "name_distr.h" -#include "addr.h" -#include "node_subscr.h" -#include "subscr.h" -#include "port.h" -#include "cluster.h" -#include "bcast.h" - -int tipc_nametbl_size = 1024; /* must be a power of 2 */ - -/** - * struct sub_seq - container for all published instances of a name sequence - * @lower: name sequence lower bound - * @upper: name sequence upper bound - * @node_list: circular list of matching publications with >= node scope - * @cluster_list: circular list of matching publications with >= cluster scope - * @zone_list: circular list of matching publications with >= zone scope - */ - -struct sub_seq { - u32 lower; - u32 upper; - struct publication *node_list; - struct publication *cluster_list; - struct publication *zone_list; -}; - -/** - * struct name_seq - container for all published instances of a name type - * @type: 32 bit 'type' value for name sequence - * @sseq: pointer to dynamically-sized array of sub-sequences of this 'type'; - * sub-sequences are sorted in ascending order - * @alloc: number of sub-sequences currently in array - * @first_free: upper bound of highest sub-sequence + 1 - * @ns_list: links to adjacent name sequences in hash chain - * @subscriptions: list of subscriptions for this 'type' - * @lock: spinlock controlling access to name sequence structure - */ - -struct name_seq { - u32 type; - struct sub_seq *sseqs; - u32 alloc; - u32 first_free; - struct hlist_node ns_list; - struct list_head subscriptions; - spinlock_t lock; -}; - -/** - * struct name_table - table containing all existing port name publications - * @types: pointer to fixed-sized array of name sequence lists, - * accessed via hashing on 'type'; name sequence lists are *not* sorted - * @local_publ_count: number of publications issued by this node - */ - -struct name_table { - struct hlist_head *types; - u32 local_publ_count; -}; - -struct name_table table = { NULL } ; -static atomic_t rsv_publ_ok = ATOMIC_INIT(0); -rwlock_t nametbl_lock = RW_LOCK_UNLOCKED; - - -static inline int hash(int x) -{ - return(x & (tipc_nametbl_size - 1)); -} - -/** - * publ_create - create a publication structure - */ - -static struct publication *publ_create(u32 type, u32 lower, u32 upper, - u32 scope, u32 node, u32 port_ref, - u32 key) -{ - struct publication *publ = - (struct publication *)kmalloc(sizeof(*publ), GFP_ATOMIC); - if (publ == NULL) { - warn("Memory squeeze; failed to create publication\n"); - return 0; - } - - memset(publ, 0, sizeof(*publ)); - publ->type = type; - publ->lower = lower; - publ->upper = upper; - publ->scope = scope; - publ->node = node; - publ->ref = port_ref; - publ->key = key; - INIT_LIST_HEAD(&publ->local_list); - INIT_LIST_HEAD(&publ->pport_list); - INIT_LIST_HEAD(&publ->subscr.nodesub_list); - return publ; -} - -/** - * subseq_alloc - allocate a specified number of sub-sequence structures - */ - -struct sub_seq *subseq_alloc(u32 cnt) -{ - u32 sz = cnt * sizeof(struct sub_seq); - struct sub_seq *sseq = (struct sub_seq *)kmalloc(sz, GFP_ATOMIC); - - if (sseq) - memset(sseq, 0, sz); - return sseq; -} - -/** - * nameseq_create - create a name sequence structure for the specified 'type' - * - * Allocates a single sub-sequence structure and sets it to all 0's. - */ - -struct name_seq *nameseq_create(u32 type, struct hlist_head *seq_head) -{ - struct name_seq *nseq = - (struct name_seq *)kmalloc(sizeof(*nseq), GFP_ATOMIC); - struct sub_seq *sseq = subseq_alloc(1); - - if (!nseq || !sseq) { - warn("Memory squeeze; failed to create name sequence\n"); - kfree(nseq); - kfree(sseq); - return 0; - } - - memset(nseq, 0, sizeof(*nseq)); - nseq->lock = SPIN_LOCK_UNLOCKED; - nseq->type = type; - nseq->sseqs = sseq; - dbg("nameseq_create() nseq = %x type %u, ssseqs %x, ff: %u\n", - nseq, type, nseq->sseqs, nseq->first_free); - nseq->alloc = 1; - INIT_HLIST_NODE(&nseq->ns_list); - INIT_LIST_HEAD(&nseq->subscriptions); - hlist_add_head(&nseq->ns_list, seq_head); - return nseq; -} - -/** - * nameseq_find_subseq - find sub-sequence (if any) matching a name instance - * - * Very time-critical, so binary searches through sub-sequence array. - */ - -static inline struct sub_seq *nameseq_find_subseq(struct name_seq *nseq, - u32 instance) -{ - struct sub_seq *sseqs = nseq->sseqs; - int low = 0; - int high = nseq->first_free - 1; - int mid; - - while (low <= high) { - mid = (low + high) / 2; - if (instance < sseqs[mid].lower) - high = mid - 1; - else if (instance > sseqs[mid].upper) - low = mid + 1; - else - return &sseqs[mid]; - } - return 0; -} - -/** - * nameseq_locate_subseq - determine position of name instance in sub-sequence - * - * Returns index in sub-sequence array of the entry that contains the specified - * instance value; if no entry contains that value, returns the position - * where a new entry for it would be inserted in the array. - * - * Note: Similar to binary search code for locating a sub-sequence. - */ - -static u32 nameseq_locate_subseq(struct name_seq *nseq, u32 instance) -{ - struct sub_seq *sseqs = nseq->sseqs; - int low = 0; - int high = nseq->first_free - 1; - int mid; - - while (low <= high) { - mid = (low + high) / 2; - if (instance < sseqs[mid].lower) - high = mid - 1; - else if (instance > sseqs[mid].upper) - low = mid + 1; - else - return mid; - } - return low; -} - -/** - * nameseq_insert_publ - - */ - -struct publication *nameseq_insert_publ(struct name_seq *nseq, - u32 type, u32 lower, u32 upper, - u32 scope, u32 node, u32 port, u32 key) -{ - struct subscription *s; - struct subscription *st; - struct publication *publ; - struct sub_seq *sseq; - int created_subseq = 0; - - assert(nseq->first_free <= nseq->alloc); - sseq = nameseq_find_subseq(nseq, lower); - dbg("nameseq_ins: for seq %x,<%u,%u>, found sseq %x\n", - nseq, type, lower, sseq); - if (sseq) { - - /* Lower end overlaps existing entry => need an exact match */ - - if ((sseq->lower != lower) || (sseq->upper != upper)) { - warn("Overlapping publ <%u,%u,%u>\n", type, lower, upper); - return 0; - } - } else { - u32 inspos; - struct sub_seq *freesseq; - - /* Find where lower end should be inserted */ - - inspos = nameseq_locate_subseq(nseq, lower); - - /* Fail if upper end overlaps into an existing entry */ - - if ((inspos < nseq->first_free) && - (upper >= nseq->sseqs[inspos].lower)) { - warn("Overlapping publ <%u,%u,%u>\n", type, lower, upper); - return 0; - } - - /* Ensure there is space for new sub-sequence */ - - if (nseq->first_free == nseq->alloc) { - struct sub_seq *sseqs = nseq->sseqs; - nseq->sseqs = subseq_alloc(nseq->alloc * 2); - if (nseq->sseqs != NULL) { - memcpy(nseq->sseqs, sseqs, - nseq->alloc * sizeof (struct sub_seq)); - kfree(sseqs); - dbg("Allocated %u sseqs\n", nseq->alloc); - nseq->alloc *= 2; - } else { - warn("Memory squeeze; failed to create sub-sequence\n"); - return 0; - } - } - dbg("Have %u sseqs for type %u\n", nseq->alloc, type); - - /* Insert new sub-sequence */ - - dbg("ins in pos %u, ff = %u\n", inspos, nseq->first_free); - sseq = &nseq->sseqs[inspos]; - freesseq = &nseq->sseqs[nseq->first_free]; - memmove(sseq + 1, sseq, (freesseq - sseq) * sizeof (*sseq)); - memset(sseq, 0, sizeof (*sseq)); - nseq->first_free++; - sseq->lower = lower; - sseq->upper = upper; - created_subseq = 1; - } - dbg("inserting (%u %u %u) from %x:%u into sseq %x(%u,%u) of seq %x\n", - type, lower, upper, node, port, sseq, - sseq->lower, sseq->upper, nseq); - - /* Insert a publication: */ - - publ = publ_create(type, lower, upper, scope, node, port, key); - if (!publ) - return 0; - dbg("inserting publ %x, node=%x publ->node=%x, subscr->node=%x\n", - publ, node, publ->node, publ->subscr.node); - - if (!sseq->zone_list) - sseq->zone_list = publ->zone_list_next = publ; - else { - publ->zone_list_next = sseq->zone_list->zone_list_next; - sseq->zone_list->zone_list_next = publ; - } - - if (in_own_cluster(node)) { - if (!sseq->cluster_list) - sseq->cluster_list = publ->cluster_list_next = publ; - else { - publ->cluster_list_next = - sseq->cluster_list->cluster_list_next; - sseq->cluster_list->cluster_list_next = publ; - } - } - - if (node == tipc_own_addr) { - if (!sseq->node_list) - sseq->node_list = publ->node_list_next = publ; - else { - publ->node_list_next = sseq->node_list->node_list_next; - sseq->node_list->node_list_next = publ; - } - } - - /* - * Any subscriptions waiting for notification? - */ - list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { - dbg("calling report_overlap()\n"); - subscr_report_overlap(s, - publ->lower, - publ->upper, - TIPC_PUBLISHED, - publ->ref, - publ->node, - created_subseq); - } - return publ; -} - -/** - * nameseq_remove_publ - - */ - -struct publication *nameseq_remove_publ(struct name_seq *nseq, u32 inst, - u32 node, u32 ref, u32 key) -{ - struct publication *publ; - struct publication *prev; - struct sub_seq *sseq = nameseq_find_subseq(nseq, inst); - struct sub_seq *free; - struct subscription *s, *st; - int removed_subseq = 0; - - assert(nseq); - - if (!sseq) { - int i; - - warn("Withdraw unknown <%u,%u>?\n", nseq->type, inst); - assert(nseq->sseqs); - dbg("Dumping subseqs %x for %x, alloc = %u,ff=%u\n", - nseq->sseqs, nseq, nseq->alloc, - nseq->first_free); - for (i = 0; i < nseq->first_free; i++) { - dbg("Subseq %u(%x): lower = %u,upper = %u\n", - i, &nseq->sseqs[i], nseq->sseqs[i].lower, - nseq->sseqs[i].upper); - } - return 0; - } - dbg("nameseq_remove: seq: %x, sseq %x, <%u,%u> key %u\n", - nseq, sseq, nseq->type, inst, key); - - prev = sseq->zone_list; - publ = sseq->zone_list->zone_list_next; - while ((publ->key != key) || (publ->ref != ref) || - (publ->node && (publ->node != node))) { - prev = publ; - publ = publ->zone_list_next; - assert(prev != sseq->zone_list); - } - if (publ != sseq->zone_list) - prev->zone_list_next = publ->zone_list_next; - else if (publ->zone_list_next != publ) { - prev->zone_list_next = publ->zone_list_next; - sseq->zone_list = publ->zone_list_next; - } else { - sseq->zone_list = 0; - } - - if (in_own_cluster(node)) { - prev = sseq->cluster_list; - publ = sseq->cluster_list->cluster_list_next; - while ((publ->key != key) || (publ->ref != ref) || - (publ->node && (publ->node != node))) { - prev = publ; - publ = publ->cluster_list_next; - assert(prev != sseq->cluster_list); - } - if (publ != sseq->cluster_list) - prev->cluster_list_next = publ->cluster_list_next; - else if (publ->cluster_list_next != publ) { - prev->cluster_list_next = publ->cluster_list_next; - sseq->cluster_list = publ->cluster_list_next; - } else { - sseq->cluster_list = 0; - } - } - - if (node == tipc_own_addr) { - prev = sseq->node_list; - publ = sseq->node_list->node_list_next; - while ((publ->key != key) || (publ->ref != ref) || - (publ->node && (publ->node != node))) { - prev = publ; - publ = publ->node_list_next; - assert(prev != sseq->node_list); - } - if (publ != sseq->node_list) - prev->node_list_next = publ->node_list_next; - else if (publ->node_list_next != publ) { - prev->node_list_next = publ->node_list_next; - sseq->node_list = publ->node_list_next; - } else { - sseq->node_list = 0; - } - } - assert(!publ->node || (publ->node == node)); - assert(publ->ref == ref); - assert(publ->key == key); - - /* - * Contract subseq list if no more publications: - */ - if (!sseq->node_list && !sseq->cluster_list && !sseq->zone_list) { - free = &nseq->sseqs[nseq->first_free--]; - memmove(sseq, sseq + 1, (free - (sseq + 1)) * sizeof (*sseq)); - removed_subseq = 1; - } - - /* - * Any subscriptions waiting ? - */ - list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { - subscr_report_overlap(s, - publ->lower, - publ->upper, - TIPC_WITHDRAWN, - publ->ref, - publ->node, - removed_subseq); - } - return publ; -} - -/** - * nameseq_subscribe: attach a subscription, and issue - * the prescribed number of events if there is any sub- - * sequence overlapping with the requested sequence - */ - -void nameseq_subscribe(struct name_seq *nseq, struct subscription *s) -{ - struct sub_seq *sseq = nseq->sseqs; - - list_add(&s->nameseq_list, &nseq->subscriptions); - - if (!sseq) - return; - - while (sseq != &nseq->sseqs[nseq->first_free]) { - struct publication *zl = sseq->zone_list; - if (zl && subscr_overlap(s,sseq->lower,sseq->upper)) { - struct publication *crs = zl; - int must_report = 1; - - do { - subscr_report_overlap(s, - sseq->lower, - sseq->upper, - TIPC_PUBLISHED, - crs->ref, - crs->node, - must_report); - must_report = 0; - crs = crs->zone_list_next; - } while (crs != zl); - } - sseq++; - } -} - -static struct name_seq *nametbl_find_seq(u32 type) -{ - struct hlist_head *seq_head; - struct hlist_node *seq_node; - struct name_seq *ns; - - dbg("find_seq %u,(%u,0x%x) table = %p, hash[type] = %u\n", - type, ntohl(type), type, table.types, hash(type)); - - seq_head = &table.types[hash(type)]; - hlist_for_each_entry(ns, seq_node, seq_head, ns_list) { - if (ns->type == type) { - dbg("found %x\n", ns); - return ns; - } - } - - return 0; -}; - -struct publication *nametbl_insert_publ(u32 type, u32 lower, u32 upper, - u32 scope, u32 node, u32 port, u32 key) -{ - struct name_seq *seq = nametbl_find_seq(type); - - dbg("ins_publ: <%u,%x,%x> found %x\n", type, lower, upper, seq); - if (lower > upper) { - warn("Failed to publish illegal <%u,%u,%u>\n", - type, lower, upper); - return 0; - } - - dbg("Publishing <%u,%u,%u> from %x\n", type, lower, upper, node); - if (!seq) { - seq = nameseq_create(type, &table.types[hash(type)]); - dbg("nametbl_insert_publ: created %x\n", seq); - } - if (!seq) - return 0; - - assert(seq->type == type); - return nameseq_insert_publ(seq, type, lower, upper, - scope, node, port, key); -} - -struct publication *nametbl_remove_publ(u32 type, u32 lower, - u32 node, u32 ref, u32 key) -{ - struct publication *publ; - struct name_seq *seq = nametbl_find_seq(type); - - if (!seq) - return 0; - - dbg("Withdrawing <%u,%u> from %x\n", type, lower, node); - publ = nameseq_remove_publ(seq, lower, node, ref, key); - - if (!seq->first_free && list_empty(&seq->subscriptions)) { - hlist_del_init(&seq->ns_list); - kfree(seq->sseqs); - kfree(seq); - } - return publ; -} - -/* - * nametbl_translate(): Translate tipc_name -> tipc_portid. - * Very time-critical. - * - * Note: on entry 'destnode' is the search domain used during translation; - * on exit it passes back the node address of the matching port (if any) - */ - -u32 nametbl_translate(u32 type, u32 instance, u32 *destnode) -{ - struct sub_seq *sseq; - struct publication *publ = 0; - struct name_seq *seq; - u32 ref; - - if (!in_scope(*destnode, tipc_own_addr)) - return 0; - - read_lock_bh(&nametbl_lock); - seq = nametbl_find_seq(type); - if (unlikely(!seq)) - goto not_found; - sseq = nameseq_find_subseq(seq, instance); - if (unlikely(!sseq)) - goto not_found; - spin_lock_bh(&seq->lock); - - /* Closest-First Algorithm: */ - if (likely(!*destnode)) { - publ = sseq->node_list; - if (publ) { - sseq->node_list = publ->node_list_next; -found: - ref = publ->ref; - *destnode = publ->node; - spin_unlock_bh(&seq->lock); - read_unlock_bh(&nametbl_lock); - return ref; - } - publ = sseq->cluster_list; - if (publ) { - sseq->cluster_list = publ->cluster_list_next; - goto found; - } - publ = sseq->zone_list; - if (publ) { - sseq->zone_list = publ->zone_list_next; - goto found; - } - } - - /* Round-Robin Algorithm: */ - else if (*destnode == tipc_own_addr) { - publ = sseq->node_list; - if (publ) { - sseq->node_list = publ->node_list_next; - goto found; - } - } else if (in_own_cluster(*destnode)) { - publ = sseq->cluster_list; - if (publ) { - sseq->cluster_list = publ->cluster_list_next; - goto found; - } - } else { - publ = sseq->zone_list; - if (publ) { - sseq->zone_list = publ->zone_list_next; - goto found; - } - } - spin_unlock_bh(&seq->lock); -not_found: - *destnode = 0; - read_unlock_bh(&nametbl_lock); - return 0; -} - -/** - * nametbl_mc_translate - find multicast destinations - * - * Creates list of all local ports that overlap the given multicast address; - * also determines if any off-node ports overlap. - * - * Note: Publications with a scope narrower than 'limit' are ignored. - * (i.e. local node-scope publications mustn't receive messages arriving - * from another node, even if the multcast link brought it here) - * - * Returns non-zero if any off-node ports overlap - */ - -int nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, - struct port_list *dports) -{ - struct name_seq *seq; - struct sub_seq *sseq; - struct sub_seq *sseq_stop; - int res = 0; - - read_lock_bh(&nametbl_lock); - seq = nametbl_find_seq(type); - if (!seq) - goto exit; - - spin_lock_bh(&seq->lock); - - sseq = seq->sseqs + nameseq_locate_subseq(seq, lower); - sseq_stop = seq->sseqs + seq->first_free; - for (; sseq != sseq_stop; sseq++) { - struct publication *publ; - - if (sseq->lower > upper) - break; - publ = sseq->cluster_list; - if (publ && (publ->scope <= limit)) - do { - if (publ->node == tipc_own_addr) - port_list_add(dports, publ->ref); - else - res = 1; - publ = publ->cluster_list_next; - } while (publ != sseq->cluster_list); - } - - spin_unlock_bh(&seq->lock); -exit: - read_unlock_bh(&nametbl_lock); - return res; -} - -/** - * nametbl_publish_rsv - publish port name using a reserved name type - */ - -int nametbl_publish_rsv(u32 ref, unsigned int scope, - struct tipc_name_seq const *seq) -{ - int res; - - atomic_inc(&rsv_publ_ok); - res = tipc_publish(ref, scope, seq); - atomic_dec(&rsv_publ_ok); - return res; -} - -/** - * nametbl_publish - add name publication to network name tables - */ - -struct publication *nametbl_publish(u32 type, u32 lower, u32 upper, - u32 scope, u32 port_ref, u32 key) -{ - struct publication *publ; - - if (table.local_publ_count >= tipc_max_publications) { - warn("Failed publish: max %u local publication\n", - tipc_max_publications); - return 0; - } - if ((type < TIPC_RESERVED_TYPES) && !atomic_read(&rsv_publ_ok)) { - warn("Failed to publish reserved name <%u,%u,%u>\n", - type, lower, upper); - return 0; - } - - write_lock_bh(&nametbl_lock); - table.local_publ_count++; - publ = nametbl_insert_publ(type, lower, upper, scope, - tipc_own_addr, port_ref, key); - if (publ && (scope != TIPC_NODE_SCOPE)) { - named_publish(publ); - } - write_unlock_bh(&nametbl_lock); - return publ; -} - -/** - * nametbl_withdraw - withdraw name publication from network name tables - */ - -int nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) -{ - struct publication *publ; - - dbg("nametbl_withdraw:<%d,%d,%d>\n", type, lower, key); - write_lock_bh(&nametbl_lock); - publ = nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); - if (publ) { - table.local_publ_count--; - if (publ->scope != TIPC_NODE_SCOPE) - named_withdraw(publ); - write_unlock_bh(&nametbl_lock); - list_del_init(&publ->pport_list); - kfree(publ); - return 1; - } - write_unlock_bh(&nametbl_lock); - return 0; -} - -/** - * nametbl_subscribe - add a subscription object to the name table - */ - -void -nametbl_subscribe(struct subscription *s) -{ - u32 type = s->seq.type; - struct name_seq *seq; - - write_lock_bh(&nametbl_lock); - seq = nametbl_find_seq(type); - if (!seq) { - seq = nameseq_create(type, &table.types[hash(type)]); - } - if (seq){ - spin_lock_bh(&seq->lock); - dbg("nametbl_subscribe:found %x for <%u,%u,%u>\n", - seq, type, s->seq.lower, s->seq.upper); - assert(seq->type == type); - nameseq_subscribe(seq, s); - spin_unlock_bh(&seq->lock); - } - write_unlock_bh(&nametbl_lock); -} - -/** - * nametbl_unsubscribe - remove a subscription object from name table - */ - -void -nametbl_unsubscribe(struct subscription *s) -{ - struct name_seq *seq; - - write_lock_bh(&nametbl_lock); - seq = nametbl_find_seq(s->seq.type); - if (seq != NULL){ - spin_lock_bh(&seq->lock); - list_del_init(&s->nameseq_list); - spin_unlock_bh(&seq->lock); - if ((seq->first_free == 0) && list_empty(&seq->subscriptions)) { - hlist_del_init(&seq->ns_list); - kfree(seq->sseqs); - kfree(seq); - } - } - write_unlock_bh(&nametbl_lock); -} - - -/** - * subseq_list: print specified sub-sequence contents into the given buffer - */ - -static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, - u32 index) -{ - char portIdStr[27]; - char *scopeStr; - struct publication *publ = sseq->zone_list; - - tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); - - if (depth == 2 || !publ) { - tipc_printf(buf, "\n"); - return; - } - - do { - sprintf (portIdStr, "<%u.%u.%u:%u>", - tipc_zone(publ->node), tipc_cluster(publ->node), - tipc_node(publ->node), publ->ref); - tipc_printf(buf, "%-26s ", portIdStr); - if (depth > 3) { - if (publ->node != tipc_own_addr) - scopeStr = ""; - else if (publ->scope == TIPC_NODE_SCOPE) - scopeStr = "node"; - else if (publ->scope == TIPC_CLUSTER_SCOPE) - scopeStr = "cluster"; - else - scopeStr = "zone"; - tipc_printf(buf, "%-10u %s", publ->key, scopeStr); - } - - publ = publ->zone_list_next; - if (publ == sseq->zone_list) - break; - - tipc_printf(buf, "\n%33s", " "); - } while (1); - - tipc_printf(buf, "\n"); -} - -/** - * nameseq_list: print specified name sequence contents into the given buffer - */ - -static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, - u32 type, u32 lowbound, u32 upbound, u32 index) -{ - struct sub_seq *sseq; - char typearea[11]; - - sprintf(typearea, "%-10u", seq->type); - - if (depth == 1) { - tipc_printf(buf, "%s\n", typearea); - return; - } - - for (sseq = seq->sseqs; sseq != &seq->sseqs[seq->first_free]; sseq++) { - if ((lowbound <= sseq->upper) && (upbound >= sseq->lower)) { - tipc_printf(buf, "%s ", typearea); - subseq_list(sseq, buf, depth, index); - sprintf(typearea, "%10s", " "); - } - } -} - -/** - * nametbl_header - print name table header into the given buffer - */ - -static void nametbl_header(struct print_buf *buf, u32 depth) -{ - tipc_printf(buf, "Type "); - - if (depth > 1) - tipc_printf(buf, "Lower Upper "); - if (depth > 2) - tipc_printf(buf, "Port Identity "); - if (depth > 3) - tipc_printf(buf, "Publication"); - - tipc_printf(buf, "\n-----------"); - - if (depth > 1) - tipc_printf(buf, "--------------------- "); - if (depth > 2) - tipc_printf(buf, "-------------------------- "); - if (depth > 3) - tipc_printf(buf, "------------------"); - - tipc_printf(buf, "\n"); -} - -/** - * nametbl_list - print specified name table contents into the given buffer - */ - -static void nametbl_list(struct print_buf *buf, u32 depth_info, - u32 type, u32 lowbound, u32 upbound) -{ - struct hlist_head *seq_head; - struct hlist_node *seq_node; - struct name_seq *seq; - int all_types; - u32 depth; - u32 i; - - all_types = (depth_info & TIPC_NTQ_ALLTYPES); - depth = (depth_info & ~TIPC_NTQ_ALLTYPES); - - if (depth == 0) - return; - - if (all_types) { - /* display all entries in name table to specified depth */ - nametbl_header(buf, depth); - lowbound = 0; - upbound = ~0; - for (i = 0; i < tipc_nametbl_size; i++) { - seq_head = &table.types[i]; - hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { - nameseq_list(seq, buf, depth, seq->type, - lowbound, upbound, i); - } - } - } else { - /* display only the sequence that matches the specified type */ - if (upbound < lowbound) { - tipc_printf(buf, "invalid name sequence specified\n"); - return; - } - nametbl_header(buf, depth); - i = hash(type); - seq_head = &table.types[i]; - hlist_for_each_entry(seq, seq_node, seq_head, ns_list) { - if (seq->type == type) { - nameseq_list(seq, buf, depth, type, - lowbound, upbound, i); - break; - } - } - } -} - -void nametbl_print(struct print_buf *buf, const char *str) -{ - tipc_printf(buf, str); - read_lock_bh(&nametbl_lock); - nametbl_list(buf, 0, 0, 0, 0); - read_unlock_bh(&nametbl_lock); -} - -#define MAX_NAME_TBL_QUERY 32768 - -struct sk_buff *nametbl_get(const void *req_tlv_area, int req_tlv_space) -{ - struct sk_buff *buf; - struct tipc_name_table_query *argv; - struct tlv_desc *rep_tlv; - struct print_buf b; - int str_len; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NAME_TBL_QUERY)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - buf = cfg_reply_alloc(TLV_SPACE(MAX_NAME_TBL_QUERY)); - if (!buf) - return NULL; - - rep_tlv = (struct tlv_desc *)buf->data; - printbuf_init(&b, TLV_DATA(rep_tlv), MAX_NAME_TBL_QUERY); - argv = (struct tipc_name_table_query *)TLV_DATA(req_tlv_area); - read_lock_bh(&nametbl_lock); - nametbl_list(&b, ntohl(argv->depth), ntohl(argv->type), - ntohl(argv->lowbound), ntohl(argv->upbound)); - read_unlock_bh(&nametbl_lock); - str_len = printbuf_validate(&b); - - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - -void nametbl_dump(void) -{ - nametbl_list(CONS, 0, 0, 0, 0); -} - -int nametbl_init(void) -{ - int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; - - table.types = (struct hlist_head *)kmalloc(array_size, GFP_ATOMIC); - if (!table.types) - return -ENOMEM; - - write_lock_bh(&nametbl_lock); - memset(table.types, 0, array_size); - table.local_publ_count = 0; - write_unlock_bh(&nametbl_lock); - return 0; -} - -void nametbl_stop(void) -{ - struct hlist_head *seq_head; - struct hlist_node *seq_node; - struct hlist_node *tmp; - struct name_seq *seq; - u32 i; - - if (!table.types) - return; - - write_lock_bh(&nametbl_lock); - for (i = 0; i < tipc_nametbl_size; i++) { - seq_head = &table.types[i]; - hlist_for_each_entry_safe(seq, seq_node, tmp, seq_head, ns_list) { - struct sub_seq *sseq = seq->sseqs; - - for (; sseq != &seq->sseqs[seq->first_free]; sseq++) { - struct publication *publ = sseq->zone_list; - assert(publ); - do { - struct publication *next = - publ->zone_list_next; - kfree(publ); - publ = next; - } - while (publ != sseq->zone_list); - } - } - } - kfree(table.types); - table.types = NULL; - write_unlock_bh(&nametbl_lock); -} diff --git a/trunk/net/tipc/name_table.h b/trunk/net/tipc/name_table.h deleted file mode 100644 index f82693384f60..000000000000 --- a/trunk/net/tipc/name_table.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * net/tipc/name_table.h: Include file for TIPC name table code - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_NAME_TABLE_H -#define _TIPC_NAME_TABLE_H - -#include "node_subscr.h" - -struct subscription; -struct port_list; - -/* - * TIPC name types reserved for internal TIPC use (both current and planned) - */ - -#define TIPC_ZM_SRV 3 /* zone master service name type */ - - -/** - * struct publication - info about a published (name or) name sequence - * @type: name sequence type - * @lower: name sequence lower bound - * @upper: name sequence upper bound - * @scope: scope of publication - * @node: network address of publishing port's node - * @ref: publishing port - * @key: publication key - * @subscr: subscription to "node down" event (for off-node publications only) - * @local_list: adjacent entries in list of publications made by this node - * @pport_list: adjacent entries in list of publications made by this port - * @node_list: next matching name seq publication with >= node scope - * @cluster_list: next matching name seq publication with >= cluster scope - * @zone_list: next matching name seq publication with >= zone scope - * - * Note that the node list, cluster list, and zone list are circular lists. - */ - -struct publication { - u32 type; - u32 lower; - u32 upper; - u32 scope; - u32 node; - u32 ref; - u32 key; - struct node_subscr subscr; - struct list_head local_list; - struct list_head pport_list; - struct publication *node_list_next; - struct publication *cluster_list_next; - struct publication *zone_list_next; -}; - - -extern rwlock_t nametbl_lock; - -struct sk_buff *nametbl_get(const void *req_tlv_area, int req_tlv_space); -u32 nametbl_translate(u32 type, u32 instance, u32 *node); -int nametbl_mc_translate(u32 type, u32 lower, u32 upper, u32 limit, - struct port_list *dports); -int nametbl_publish_rsv(u32 ref, unsigned int scope, - struct tipc_name_seq const *seq); -struct publication *nametbl_publish(u32 type, u32 lower, u32 upper, - u32 scope, u32 port_ref, u32 key); -int nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key); -struct publication *nametbl_insert_publ(u32 type, u32 lower, u32 upper, - u32 scope, u32 node, u32 ref, u32 key); -struct publication *nametbl_remove_publ(u32 type, u32 lower, - u32 node, u32 ref, u32 key); -void nametbl_subscribe(struct subscription *s); -void nametbl_unsubscribe(struct subscription *s); -int nametbl_init(void); -void nametbl_stop(void); - -#endif diff --git a/trunk/net/tipc/net.c b/trunk/net/tipc/net.c deleted file mode 100644 index 6826b493c1d6..000000000000 --- a/trunk/net/tipc/net.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * net/tipc/net.c: TIPC network routing code - * - * Copyright (c) 1995-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "bearer.h" -#include "net.h" -#include "zone.h" -#include "addr.h" -#include "name_table.h" -#include "name_distr.h" -#include "subscr.h" -#include "link.h" -#include "msg.h" -#include "port.h" -#include "bcast.h" -#include "discover.h" -#include "config.h" - -/* - * The TIPC locking policy is designed to ensure a very fine locking - * granularity, permitting complete parallel access to individual - * port and node/link instances. The code consists of three major - * locking domains, each protected with their own disjunct set of locks. - * - * 1: The routing hierarchy. - * Comprises the structures 'zone', 'cluster', 'node', 'link' - * and 'bearer'. The whole hierarchy is protected by a big - * read/write lock, net_lock, to enssure that nothing is added - * or removed while code is accessing any of these structures. - * This layer must not be called from the two others while they - * hold any of their own locks. - * Neither must it itself do any upcalls to the other two before - * it has released net_lock and other protective locks. - * - * Within the net_lock domain there are two sub-domains;'node' and - * 'bearer', where local write operations are permitted, - * provided that those are protected by individual spin_locks - * per instance. Code holding net_lock(read) and a node spin_lock - * is permitted to poke around in both the node itself and its - * subordinate links. I.e, it can update link counters and queues, - * change link state, send protocol messages, and alter the - * "active_links" array in the node; but it can _not_ remove a link - * or a node from the overall structure. - * Correspondingly, individual bearers may change status within a - * net_lock(read), protected by an individual spin_lock ber bearer - * instance, but it needs net_lock(write) to remove/add any bearers. - * - * - * 2: The transport level of the protocol. - * This consists of the structures port, (and its user level - * representations, such as user_port and tipc_sock), reference and - * tipc_user (port.c, reg.c, socket.c). - * - * This layer has four different locks: - * - The tipc_port spin_lock. This is protecting each port instance - * from parallel data access and removal. Since we can not place - * this lock in the port itself, it has been placed in the - * corresponding reference table entry, which has the same life - * cycle as the module. This entry is difficult to access from - * outside the TIPC core, however, so a pointer to the lock has - * been added in the port instance, -to be used for unlocking - * only. - * - A read/write lock to protect the reference table itself (teg.c). - * (Nobody is using read-only access to this, so it can just as - * well be changed to a spin_lock) - * - A spin lock to protect the registry of kernel/driver users (reg.c) - * - A global spin_lock (port_lock), which only task is to ensure - * consistency where more than one port is involved in an operation, - * i.e., whe a port is part of a linked list of ports. - * There are two such lists; 'port_list', which is used for management, - * and 'wait_list', which is used to queue ports during congestion. - * - * 3: The name table (name_table.c, name_distr.c, subscription.c) - * - There is one big read/write-lock (nametbl_lock) protecting the - * overall name table structure. Nothing must be added/removed to - * this structure without holding write access to it. - * - There is one local spin_lock per sub_sequence, which can be seen - * as a sub-domain to the nametbl_lock domain. It is used only - * for translation operations, and is needed because a translation - * steps the root of the 'publication' linked list between each lookup. - * This is always used within the scope of a nametbl_lock(read). - * - A local spin_lock protecting the queue of subscriber events. -*/ - -rwlock_t net_lock = RW_LOCK_UNLOCKED; -struct network net = { 0 }; - -struct node *net_select_remote_node(u32 addr, u32 ref) -{ - return zone_select_remote_node(net.zones[tipc_zone(addr)], addr, ref); -} - -u32 net_select_router(u32 addr, u32 ref) -{ - return zone_select_router(net.zones[tipc_zone(addr)], addr, ref); -} - - -u32 net_next_node(u32 a) -{ - if (net.zones[tipc_zone(a)]) - return zone_next_node(a); - return 0; -} - -void net_remove_as_router(u32 router) -{ - u32 z_num; - - for (z_num = 1; z_num <= tipc_max_zones; z_num++) { - if (!net.zones[z_num]) - continue; - zone_remove_as_router(net.zones[z_num], router); - } -} - -void net_send_external_routes(u32 dest) -{ - u32 z_num; - - for (z_num = 1; z_num <= tipc_max_zones; z_num++) { - if (net.zones[z_num]) - zone_send_external_routes(net.zones[z_num], dest); - } -} - -int net_init(void) -{ - u32 sz = sizeof(struct _zone *) * (tipc_max_zones + 1); - - memset(&net, 0, sizeof(net)); - net.zones = (struct _zone **)kmalloc(sz, GFP_ATOMIC); - if (!net.zones) { - return -ENOMEM; - } - memset(net.zones, 0, sz); - return TIPC_OK; -} - -void net_stop(void) -{ - u32 z_num; - - if (!net.zones) - return; - - for (z_num = 1; z_num <= tipc_max_zones; z_num++) { - zone_delete(net.zones[z_num]); - } - kfree(net.zones); - net.zones = 0; -} - -static void net_route_named_msg(struct sk_buff *buf) -{ - struct tipc_msg *msg = buf_msg(buf); - u32 dnode; - u32 dport; - - if (!msg_named(msg)) { - msg_dbg(msg, "net->drop_nam:"); - buf_discard(buf); - return; - } - - dnode = addr_domain(msg_lookup_scope(msg)); - dport = nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode); - dbg("net->lookup<%u,%u>-><%u,%x>\n", - msg_nametype(msg), msg_nameinst(msg), dport, dnode); - if (dport) { - msg_set_destnode(msg, dnode); - msg_set_destport(msg, dport); - net_route_msg(buf); - return; - } - msg_dbg(msg, "net->rej:NO NAME: "); - tipc_reject_msg(buf, TIPC_ERR_NO_NAME); -} - -void net_route_msg(struct sk_buff *buf) -{ - struct tipc_msg *msg; - u32 dnode; - - if (!buf) - return; - msg = buf_msg(buf); - - msg_incr_reroute_cnt(msg); - if (msg_reroute_cnt(msg) > 6) { - if (msg_errcode(msg)) { - msg_dbg(msg, "NET>DISC>:"); - buf_discard(buf); - } else { - msg_dbg(msg, "NET>REJ>:"); - tipc_reject_msg(buf, msg_destport(msg) ? - TIPC_ERR_NO_PORT : TIPC_ERR_NO_NAME); - } - return; - } - - msg_dbg(msg, "net->rout: "); - - /* Handle message for this node */ - dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg); - if (in_scope(dnode, tipc_own_addr)) { - if (msg_isdata(msg)) { - if (msg_mcast(msg)) - port_recv_mcast(buf, NULL); - else if (msg_destport(msg)) - port_recv_msg(buf); - else - net_route_named_msg(buf); - return; - } - switch (msg_user(msg)) { - case ROUTE_DISTRIBUTOR: - cluster_recv_routing_table(buf); - break; - case NAME_DISTRIBUTOR: - named_recv(buf); - break; - case CONN_MANAGER: - port_recv_proto_msg(buf); - break; - default: - msg_dbg(msg,"DROP/NET/SEND>: "); - link_send(buf, dnode, msg_link_selector(msg)); -} - -int tipc_start_net(void) -{ - char addr_string[16]; - int res; - - if (tipc_mode != TIPC_NODE_MODE) - return -ENOPROTOOPT; - - tipc_mode = TIPC_NET_MODE; - named_reinit(); - port_reinit(); - - if ((res = bearer_init()) || - (res = net_init()) || - (res = cluster_init()) || - (res = bclink_init())) { - return res; - } - subscr_stop(); - cfg_stop(); - k_signal((Handler)subscr_start, 0); - k_signal((Handler)cfg_init, 0); - info("Started in network mode\n"); - info("Own node address %s, network identity %u\n", - addr_string_fill(addr_string, tipc_own_addr), tipc_net_id); - return TIPC_OK; -} - -void tipc_stop_net(void) -{ - if (tipc_mode != TIPC_NET_MODE) - return; - write_lock_bh(&net_lock); - bearer_stop(); - tipc_mode = TIPC_NODE_MODE; - bclink_stop(); - net_stop(); - write_unlock_bh(&net_lock); - info("Left network mode \n"); -} - diff --git a/trunk/net/tipc/net.h b/trunk/net/tipc/net.h deleted file mode 100644 index 948c6d42102c..000000000000 --- a/trunk/net/tipc/net.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * net/tipc/net.h: Include file for TIPC network routing code - * - * Copyright (c) 1995-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_NET_H -#define _TIPC_NET_H - -struct _zone; - -/** - * struct network - TIPC network structure - * @zones: array of pointers to all zones within network - */ - -struct network { - struct _zone **zones; -}; - - -extern struct network net; -extern rwlock_t net_lock; - -int net_init(void); -void net_stop(void); -void net_remove_as_router(u32 router); -void net_send_external_routes(u32 dest); -void net_route_msg(struct sk_buff *buf); -struct node *net_select_remote_node(u32 addr, u32 ref); -u32 net_select_router(u32 addr, u32 ref); - -int tipc_start_net(void); -void tipc_stop_net(void); - -#endif diff --git a/trunk/net/tipc/netlink.c b/trunk/net/tipc/netlink.c deleted file mode 100644 index 19b3f4022532..000000000000 --- a/trunk/net/tipc/netlink.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * net/tipc/netlink.c: TIPC configuration handling - * - * Copyright (c) 2005-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "config.h" -#include - -static int handle_cmd(struct sk_buff *skb, struct genl_info *info) -{ - struct sk_buff *rep_buf; - struct nlmsghdr *rep_nlh; - struct nlmsghdr *req_nlh = info->nlhdr; - struct tipc_genlmsghdr *req_userhdr = info->userhdr; - int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN); - - if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) - rep_buf = cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN); - else - rep_buf = cfg_do_cmd(req_userhdr->dest, - req_userhdr->cmd, - NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN, - NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN), - hdr_space); - - if (rep_buf) { - skb_push(rep_buf, hdr_space); - rep_nlh = (struct nlmsghdr *)rep_buf->data; - memcpy(rep_nlh, req_nlh, hdr_space); - rep_nlh->nlmsg_len = rep_buf->len; - genlmsg_unicast(rep_buf, req_nlh->nlmsg_pid); - } - - return 0; -} - -static struct genl_family family = { - .id = GENL_ID_GENERATE, - .name = TIPC_GENL_NAME, - .version = TIPC_GENL_VERSION, - .hdrsize = TIPC_GENL_HDRLEN, - .maxattr = 0, -}; - -static struct genl_ops ops = { - .cmd = TIPC_GENL_CMD, - .doit = handle_cmd, -}; - -static int family_registered = 0; - -int netlink_start(void) -{ - - - if (genl_register_family(&family)) - goto err; - - family_registered = 1; - - if (genl_register_ops(&family, &ops)) - goto err_unregister; - - return 0; - - err_unregister: - genl_unregister_family(&family); - family_registered = 0; - err: - err("Failed to register netlink interface\n"); - return -EFAULT; -} - -void netlink_stop(void) -{ - if (family_registered) { - genl_unregister_family(&family); - family_registered = 0; - } -} diff --git a/trunk/net/tipc/node.c b/trunk/net/tipc/node.c deleted file mode 100644 index 05688d01138b..000000000000 --- a/trunk/net/tipc/node.c +++ /dev/null @@ -1,679 +0,0 @@ -/* - * net/tipc/node.c: TIPC node management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "config.h" -#include "node.h" -#include "cluster.h" -#include "net.h" -#include "addr.h" -#include "node_subscr.h" -#include "link.h" -#include "port.h" -#include "bearer.h" -#include "name_distr.h" -#include "net.h" - -void node_print(struct print_buf *buf, struct node *n_ptr, char *str); -static void node_lost_contact(struct node *n_ptr); -static void node_established_contact(struct node *n_ptr); - -struct node *nodes = NULL; /* sorted list of nodes within cluster */ - -u32 tipc_own_tag = 0; - -struct node *node_create(u32 addr) -{ - struct cluster *c_ptr; - struct node *n_ptr; - struct node **curr_node; - - n_ptr = kmalloc(sizeof(*n_ptr),GFP_ATOMIC); - if (n_ptr != NULL) { - memset(n_ptr, 0, sizeof(*n_ptr)); - n_ptr->addr = addr; - n_ptr->lock = SPIN_LOCK_UNLOCKED; - INIT_LIST_HEAD(&n_ptr->nsub); - - c_ptr = cluster_find(addr); - if (c_ptr == NULL) - c_ptr = cluster_create(addr); - if (c_ptr != NULL) { - n_ptr->owner = c_ptr; - cluster_attach_node(c_ptr, n_ptr); - n_ptr->last_router = -1; - - /* Insert node into ordered list */ - for (curr_node = &nodes; *curr_node; - curr_node = &(*curr_node)->next) { - if (addr < (*curr_node)->addr) { - n_ptr->next = *curr_node; - break; - } - } - (*curr_node) = n_ptr; - } else { - kfree(n_ptr); - n_ptr = NULL; - } - } - return n_ptr; -} - -void node_delete(struct node *n_ptr) -{ - if (!n_ptr) - return; - -#if 0 - /* Not needed because links are already deleted via bearer_stop() */ - - u32 l_num; - - for (l_num = 0; l_num < MAX_BEARERS; l_num++) { - link_delete(n_ptr->links[l_num]); - } -#endif - - dbg("node %x deleted\n", n_ptr->addr); - kfree(n_ptr); -} - - -/** - * node_link_up - handle addition of link - * - * Link becomes active (alone or shared) or standby, depending on its priority. - */ - -void node_link_up(struct node *n_ptr, struct link *l_ptr) -{ - struct link **active = &n_ptr->active_links[0]; - - info("Established link <%s> on network plane %c\n", - l_ptr->name, l_ptr->b_ptr->net_plane); - - if (!active[0]) { - dbg(" link %x into %x/%x\n", l_ptr, &active[0], &active[1]); - active[0] = active[1] = l_ptr; - node_established_contact(n_ptr); - return; - } - if (l_ptr->priority < active[0]->priority) { - info("Link is standby\n"); - return; - } - link_send_duplicate(active[0], l_ptr); - if (l_ptr->priority == active[0]->priority) { - active[0] = l_ptr; - return; - } - info("Link <%s> on network plane %c becomes standby\n", - active[0]->name, active[0]->b_ptr->net_plane); - active[0] = active[1] = l_ptr; -} - -/** - * node_select_active_links - select active link - */ - -static void node_select_active_links(struct node *n_ptr) -{ - struct link **active = &n_ptr->active_links[0]; - u32 i; - u32 highest_prio = 0; - - active[0] = active[1] = 0; - - for (i = 0; i < MAX_BEARERS; i++) { - struct link *l_ptr = n_ptr->links[i]; - - if (!l_ptr || !link_is_up(l_ptr) || - (l_ptr->priority < highest_prio)) - continue; - - if (l_ptr->priority > highest_prio) { - highest_prio = l_ptr->priority; - active[0] = active[1] = l_ptr; - } else { - active[1] = l_ptr; - } - } -} - -/** - * node_link_down - handle loss of link - */ - -void node_link_down(struct node *n_ptr, struct link *l_ptr) -{ - struct link **active; - - if (!link_is_active(l_ptr)) { - info("Lost standby link <%s> on network plane %c\n", - l_ptr->name, l_ptr->b_ptr->net_plane); - return; - } - info("Lost link <%s> on network plane %c\n", - l_ptr->name, l_ptr->b_ptr->net_plane); - - active = &n_ptr->active_links[0]; - if (active[0] == l_ptr) - active[0] = active[1]; - if (active[1] == l_ptr) - active[1] = active[0]; - if (active[0] == l_ptr) - node_select_active_links(n_ptr); - if (node_is_up(n_ptr)) - link_changeover(l_ptr); - else - node_lost_contact(n_ptr); -} - -int node_has_active_links(struct node *n_ptr) -{ - return (n_ptr && - ((n_ptr->active_links[0]) || (n_ptr->active_links[1]))); -} - -int node_has_redundant_links(struct node *n_ptr) -{ - return (node_has_active_links(n_ptr) && - (n_ptr->active_links[0] != n_ptr->active_links[1])); -} - -int node_has_active_routes(struct node *n_ptr) -{ - return (n_ptr && (n_ptr->last_router >= 0)); -} - -int node_is_up(struct node *n_ptr) -{ - return (node_has_active_links(n_ptr) || node_has_active_routes(n_ptr)); -} - -struct node *node_attach_link(struct link *l_ptr) -{ - struct node *n_ptr = node_find(l_ptr->addr); - - if (!n_ptr) - n_ptr = node_create(l_ptr->addr); - if (n_ptr) { - u32 bearer_id = l_ptr->b_ptr->identity; - char addr_string[16]; - - assert(bearer_id < MAX_BEARERS); - if (n_ptr->link_cnt >= 2) { - char addr_string[16]; - - err("Attempt to create third link to %s\n", - addr_string_fill(addr_string, n_ptr->addr)); - return 0; - } - - if (!n_ptr->links[bearer_id]) { - n_ptr->links[bearer_id] = l_ptr; - net.zones[tipc_zone(l_ptr->addr)]->links++; - n_ptr->link_cnt++; - return n_ptr; - } - err("Attempt to establish second link on <%s> to <%s> \n", - l_ptr->b_ptr->publ.name, - addr_string_fill(addr_string, l_ptr->addr)); - } - return 0; -} - -void node_detach_link(struct node *n_ptr, struct link *l_ptr) -{ - n_ptr->links[l_ptr->b_ptr->identity] = 0; - net.zones[tipc_zone(l_ptr->addr)]->links--; - n_ptr->link_cnt--; -} - -/* - * Routing table management - five cases to handle: - * - * 1: A link towards a zone/cluster external node comes up. - * => Send a multicast message updating routing tables of all - * system nodes within own cluster that the new destination - * can be reached via this node. - * (node.establishedContact()=>cluster.multicastNewRoute()) - * - * 2: A link towards a slave node comes up. - * => Send a multicast message updating routing tables of all - * system nodes within own cluster that the new destination - * can be reached via this node. - * (node.establishedContact()=>cluster.multicastNewRoute()) - * => Send a message to the slave node about existence - * of all system nodes within cluster: - * (node.establishedContact()=>cluster.sendLocalRoutes()) - * - * 3: A new cluster local system node becomes available. - * => Send message(s) to this particular node containing - * information about all cluster external and slave - * nodes which can be reached via this node. - * (node.establishedContact()==>network.sendExternalRoutes()) - * (node.establishedContact()==>network.sendSlaveRoutes()) - * => Send messages to all directly connected slave nodes - * containing information about the existence of the new node - * (node.establishedContact()=>cluster.multicastNewRoute()) - * - * 4: The link towards a zone/cluster external node or slave - * node goes down. - * => Send a multcast message updating routing tables of all - * nodes within cluster that the new destination can not any - * longer be reached via this node. - * (node.lostAllLinks()=>cluster.bcastLostRoute()) - * - * 5: A cluster local system node becomes unavailable. - * => Remove all references to this node from the local - * routing tables. Note: This is a completely node - * local operation. - * (node.lostAllLinks()=>network.removeAsRouter()) - * => Send messages to all directly connected slave nodes - * containing information about loss of the node - * (node.establishedContact()=>cluster.multicastLostRoute()) - * - */ - -static void node_established_contact(struct node *n_ptr) -{ - struct cluster *c_ptr; - - dbg("node_established_contact:-> %x\n", n_ptr->addr); - if (!node_has_active_routes(n_ptr)) { - k_signal((Handler)named_node_up, n_ptr->addr); - } - - /* Syncronize broadcast acks */ - n_ptr->bclink.acked = bclink_get_last_sent(); - - if (is_slave(tipc_own_addr)) - return; - if (!in_own_cluster(n_ptr->addr)) { - /* Usage case 1 (see above) */ - c_ptr = cluster_find(tipc_own_addr); - if (!c_ptr) - c_ptr = cluster_create(tipc_own_addr); - if (c_ptr) - cluster_bcast_new_route(c_ptr, n_ptr->addr, 1, - tipc_max_nodes); - return; - } - - c_ptr = n_ptr->owner; - if (is_slave(n_ptr->addr)) { - /* Usage case 2 (see above) */ - cluster_bcast_new_route(c_ptr, n_ptr->addr, 1, tipc_max_nodes); - cluster_send_local_routes(c_ptr, n_ptr->addr); - return; - } - - if (n_ptr->bclink.supported) { - nmap_add(&cluster_bcast_nodes, n_ptr->addr); - if (n_ptr->addr < tipc_own_addr) - tipc_own_tag++; - } - - /* Case 3 (see above) */ - net_send_external_routes(n_ptr->addr); - cluster_send_slave_routes(c_ptr, n_ptr->addr); - cluster_bcast_new_route(c_ptr, n_ptr->addr, LOWEST_SLAVE, - highest_allowed_slave); -} - -static void node_lost_contact(struct node *n_ptr) -{ - struct cluster *c_ptr; - struct node_subscr *ns, *tns; - char addr_string[16]; - u32 i; - - /* Clean up broadcast reception remains */ - n_ptr->bclink.gap_after = n_ptr->bclink.gap_to = 0; - while (n_ptr->bclink.deferred_head) { - struct sk_buff* buf = n_ptr->bclink.deferred_head; - n_ptr->bclink.deferred_head = buf->next; - buf_discard(buf); - } - if (n_ptr->bclink.defragm) { - buf_discard(n_ptr->bclink.defragm); - n_ptr->bclink.defragm = NULL; - } - if (in_own_cluster(n_ptr->addr) && n_ptr->bclink.supported) { - bclink_acknowledge(n_ptr, mod(n_ptr->bclink.acked + 10000)); - } - - /* Update routing tables */ - if (is_slave(tipc_own_addr)) { - net_remove_as_router(n_ptr->addr); - } else { - if (!in_own_cluster(n_ptr->addr)) { - /* Case 4 (see above) */ - c_ptr = cluster_find(tipc_own_addr); - cluster_bcast_lost_route(c_ptr, n_ptr->addr, 1, - tipc_max_nodes); - } else { - /* Case 5 (see above) */ - c_ptr = cluster_find(n_ptr->addr); - if (is_slave(n_ptr->addr)) { - cluster_bcast_lost_route(c_ptr, n_ptr->addr, 1, - tipc_max_nodes); - } else { - if (n_ptr->bclink.supported) { - nmap_remove(&cluster_bcast_nodes, - n_ptr->addr); - if (n_ptr->addr < tipc_own_addr) - tipc_own_tag--; - } - net_remove_as_router(n_ptr->addr); - cluster_bcast_lost_route(c_ptr, n_ptr->addr, - LOWEST_SLAVE, - highest_allowed_slave); - } - } - } - if (node_has_active_routes(n_ptr)) - return; - - info("Lost contact with %s\n", - addr_string_fill(addr_string, n_ptr->addr)); - - /* Abort link changeover */ - for (i = 0; i < MAX_BEARERS; i++) { - struct link *l_ptr = n_ptr->links[i]; - if (!l_ptr) - continue; - l_ptr->reset_checkpoint = l_ptr->next_in_no; - l_ptr->exp_msg_count = 0; - link_reset_fragments(l_ptr); - } - - /* Notify subscribers */ - list_for_each_entry_safe(ns, tns, &n_ptr->nsub, nodesub_list) { - ns->node = 0; - list_del_init(&ns->nodesub_list); - k_signal((Handler)ns->handle_node_down, - (unsigned long)ns->usr_handle); - } -} - -/** - * node_select_next_hop - find the next-hop node for a message - * - * Called by when cluster local lookup has failed. - */ - -struct node *node_select_next_hop(u32 addr, u32 selector) -{ - struct node *n_ptr; - u32 router_addr; - - if (!addr_domain_valid(addr)) - return 0; - - /* Look for direct link to destination processsor */ - n_ptr = node_find(addr); - if (n_ptr && node_has_active_links(n_ptr)) - return n_ptr; - - /* Cluster local system nodes *must* have direct links */ - if (!is_slave(addr) && in_own_cluster(addr)) - return 0; - - /* Look for cluster local router with direct link to node */ - router_addr = node_select_router(n_ptr, selector); - if (router_addr) - return node_select(router_addr, selector); - - /* Slave nodes can only be accessed within own cluster via a - known router with direct link -- if no router was found,give up */ - if (is_slave(addr)) - return 0; - - /* Inter zone/cluster -- find any direct link to remote cluster */ - addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0); - n_ptr = net_select_remote_node(addr, selector); - if (n_ptr && node_has_active_links(n_ptr)) - return n_ptr; - - /* Last resort -- look for any router to anywhere in remote zone */ - router_addr = net_select_router(addr, selector); - if (router_addr) - return node_select(router_addr, selector); - - return 0; -} - -/** - * node_select_router - select router to reach specified node - * - * Uses a deterministic and fair algorithm for selecting router node. - */ - -u32 node_select_router(struct node *n_ptr, u32 ref) -{ - u32 ulim; - u32 mask; - u32 start; - u32 r; - - if (!n_ptr) - return 0; - - if (n_ptr->last_router < 0) - return 0; - ulim = ((n_ptr->last_router + 1) * 32) - 1; - - /* Start entry must be random */ - mask = tipc_max_nodes; - while (mask > ulim) - mask >>= 1; - start = ref & mask; - r = start; - - /* Lookup upwards with wrap-around */ - do { - if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1) - break; - } while (++r <= ulim); - if (r > ulim) { - r = 1; - do { - if (((n_ptr->routers[r / 32]) >> (r % 32)) & 1) - break; - } while (++r < start); - assert(r != start); - } - assert(r && (r <= ulim)); - return tipc_addr(own_zone(), own_cluster(), r); -} - -void node_add_router(struct node *n_ptr, u32 router) -{ - u32 r_num = tipc_node(router); - - n_ptr->routers[r_num / 32] = - ((1 << (r_num % 32)) | n_ptr->routers[r_num / 32]); - n_ptr->last_router = tipc_max_nodes / 32; - while ((--n_ptr->last_router >= 0) && - !n_ptr->routers[n_ptr->last_router]); -} - -void node_remove_router(struct node *n_ptr, u32 router) -{ - u32 r_num = tipc_node(router); - - if (n_ptr->last_router < 0) - return; /* No routes */ - - n_ptr->routers[r_num / 32] = - ((~(1 << (r_num % 32))) & (n_ptr->routers[r_num / 32])); - n_ptr->last_router = tipc_max_nodes / 32; - while ((--n_ptr->last_router >= 0) && - !n_ptr->routers[n_ptr->last_router]); - - if (!node_is_up(n_ptr)) - node_lost_contact(n_ptr); -} - -#if 0 -void node_print(struct print_buf *buf, struct node *n_ptr, char *str) -{ - u32 i; - - tipc_printf(buf, "\n\n%s", str); - for (i = 0; i < MAX_BEARERS; i++) { - if (!n_ptr->links[i]) - continue; - tipc_printf(buf, "Links[%u]: %x, ", i, n_ptr->links[i]); - } - tipc_printf(buf, "Active links: [%x,%x]\n", - n_ptr->active_links[0], n_ptr->active_links[1]); -} -#endif - -u32 tipc_available_nodes(const u32 domain) -{ - struct node *n_ptr; - u32 cnt = 0; - - for (n_ptr = nodes; n_ptr; n_ptr = n_ptr->next) { - if (!in_scope(domain, n_ptr->addr)) - continue; - if (node_is_up(n_ptr)) - cnt++; - } - return cnt; -} - -struct sk_buff *node_get_nodes(const void *req_tlv_area, int req_tlv_space) -{ - u32 domain; - struct sk_buff *buf; - struct node *n_ptr; - struct tipc_node_info node_info; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - domain = *(u32 *)TLV_DATA(req_tlv_area); - domain = ntohl(domain); - if (!addr_domain_valid(domain)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (network address)"); - - if (!nodes) - return cfg_reply_none(); - - /* For now, get space for all other nodes - (will need to modify this when slave nodes are supported */ - - buf = cfg_reply_alloc(TLV_SPACE(sizeof(node_info)) * - (tipc_max_nodes - 1)); - if (!buf) - return NULL; - - /* Add TLVs for all nodes in scope */ - - for (n_ptr = nodes; n_ptr; n_ptr = n_ptr->next) { - if (!in_scope(domain, n_ptr->addr)) - continue; - node_info.addr = htonl(n_ptr->addr); - node_info.up = htonl(node_is_up(n_ptr)); - cfg_append_tlv(buf, TIPC_TLV_NODE_INFO, - &node_info, sizeof(node_info)); - } - - return buf; -} - -struct sk_buff *node_get_links(const void *req_tlv_area, int req_tlv_space) -{ - u32 domain; - struct sk_buff *buf; - struct node *n_ptr; - struct tipc_link_info link_info; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - domain = *(u32 *)TLV_DATA(req_tlv_area); - domain = ntohl(domain); - if (!addr_domain_valid(domain)) - return cfg_reply_error_string(TIPC_CFG_INVALID_VALUE - " (network address)"); - - if (!nodes) - return cfg_reply_none(); - - /* For now, get space for 2 links to all other nodes + bcast link - (will need to modify this when slave nodes are supported */ - - buf = cfg_reply_alloc(TLV_SPACE(sizeof(link_info)) * - (2 * (tipc_max_nodes - 1) + 1)); - if (!buf) - return NULL; - - /* Add TLV for broadcast link */ - - link_info.dest = tipc_own_addr & 0xfffff00; - link_info.dest = htonl(link_info.dest); - link_info.up = htonl(1); - sprintf(link_info.str, bc_link_name); - cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info)); - - /* Add TLVs for any other links in scope */ - - for (n_ptr = nodes; n_ptr; n_ptr = n_ptr->next) { - u32 i; - - if (!in_scope(domain, n_ptr->addr)) - continue; - for (i = 0; i < MAX_BEARERS; i++) { - if (!n_ptr->links[i]) - continue; - link_info.dest = htonl(n_ptr->addr); - link_info.up = htonl(link_is_up(n_ptr->links[i])); - strcpy(link_info.str, n_ptr->links[i]->name); - cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, - &link_info, sizeof(link_info)); - } - } - - return buf; -} diff --git a/trunk/net/tipc/node.h b/trunk/net/tipc/node.h deleted file mode 100644 index b39442badccf..000000000000 --- a/trunk/net/tipc/node.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * net/tipc/node.h: Include file for TIPC node management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_NODE_H -#define _TIPC_NODE_H - -#include "node_subscr.h" -#include "addr.h" -#include "cluster.h" -#include "bearer.h" - -/** - * struct node - TIPC node structure - * @addr: network address of node - * @lock: spinlock governing access to structure - * @owner: pointer to cluster that node belongs to - * @next: pointer to next node in sorted list of cluster's nodes - * @nsub: list of "node down" subscriptions monitoring node - * @active_links: pointers to active links to node - * @links: pointers to all links to node - * @link_cnt: number of links to node - * @permit_changeover: non-zero if node has redundant links to this system - * @routers: bitmap (used for multicluster communication) - * @last_router: (used for multicluster communication) - * @bclink: broadcast-related info - * @supported: non-zero if node supports TIPC b'cast capability - * @acked: sequence # of last outbound b'cast message acknowledged by node - * @last_in: sequence # of last in-sequence b'cast message received from node - * @gap_after: sequence # of last message not requiring a NAK request - * @gap_to: sequence # of last message requiring a NAK request - * @nack_sync: counter that determines when NAK requests should be sent - * @deferred_head: oldest OOS b'cast message received from node - * @deferred_tail: newest OOS b'cast message received from node - * @defragm: list of partially reassembled b'cast message fragments from node - */ - -struct node { - u32 addr; - spinlock_t lock; - struct cluster *owner; - struct node *next; - struct list_head nsub; - struct link *active_links[2]; - struct link *links[MAX_BEARERS]; - int link_cnt; - int permit_changeover; - u32 routers[512/32]; - int last_router; - struct { - int supported; - u32 acked; - u32 last_in; - u32 gap_after; - u32 gap_to; - u32 nack_sync; - struct sk_buff *deferred_head; - struct sk_buff *deferred_tail; - struct sk_buff *defragm; - } bclink; -}; - -extern struct node *nodes; -extern u32 tipc_own_tag; - -struct node *node_create(u32 addr); -void node_delete(struct node *n_ptr); -struct node *node_attach_link(struct link *l_ptr); -void node_detach_link(struct node *n_ptr, struct link *l_ptr); -void node_link_down(struct node *n_ptr, struct link *l_ptr); -void node_link_up(struct node *n_ptr, struct link *l_ptr); -int node_has_active_links(struct node *n_ptr); -int node_has_redundant_links(struct node *n_ptr); -u32 node_select_router(struct node *n_ptr, u32 ref); -struct node *node_select_next_hop(u32 addr, u32 selector); -int node_is_up(struct node *n_ptr); -void node_add_router(struct node *n_ptr, u32 router); -void node_remove_router(struct node *n_ptr, u32 router); -struct sk_buff *node_get_links(const void *req_tlv_area, int req_tlv_space); -struct sk_buff *node_get_nodes(const void *req_tlv_area, int req_tlv_space); - -static inline struct node *node_find(u32 addr) -{ - if (likely(in_own_cluster(addr))) - return local_nodes[tipc_node(addr)]; - else if (addr_domain_valid(addr)) { - struct cluster *c_ptr = cluster_find(addr); - - if (c_ptr) - return c_ptr->nodes[tipc_node(addr)]; - } - return 0; -} - -static inline struct node *node_select(u32 addr, u32 selector) -{ - if (likely(in_own_cluster(addr))) - return local_nodes[tipc_node(addr)]; - return node_select_next_hop(addr, selector); -} - -static inline void node_lock(struct node *n_ptr) -{ - spin_lock_bh(&n_ptr->lock); -} - -static inline void node_unlock(struct node *n_ptr) -{ - spin_unlock_bh(&n_ptr->lock); -} - -#endif diff --git a/trunk/net/tipc/node_subscr.c b/trunk/net/tipc/node_subscr.c deleted file mode 100644 index 79375927916f..000000000000 --- a/trunk/net/tipc/node_subscr.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * net/tipc/node_subscr.c: TIPC "node down" subscription handling - * - * Copyright (c) 1995-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "dbg.h" -#include "node_subscr.h" -#include "node.h" -#include "addr.h" - -/** - * nodesub_subscribe - create "node down" subscription for specified node - */ - -void nodesub_subscribe(struct node_subscr *node_sub, u32 addr, - void *usr_handle, net_ev_handler handle_down) -{ - node_sub->node = 0; - if (addr == tipc_own_addr) - return; - if (!addr_node_valid(addr)) { - warn("node_subscr with illegal %x\n", addr); - return; - } - - node_sub->handle_node_down = handle_down; - node_sub->usr_handle = usr_handle; - node_sub->node = node_find(addr); - assert(node_sub->node); - node_lock(node_sub->node); - list_add_tail(&node_sub->nodesub_list, &node_sub->node->nsub); - node_unlock(node_sub->node); -} - -/** - * nodesub_unsubscribe - cancel "node down" subscription (if any) - */ - -void nodesub_unsubscribe(struct node_subscr *node_sub) -{ - if (!node_sub->node) - return; - - node_lock(node_sub->node); - list_del_init(&node_sub->nodesub_list); - node_unlock(node_sub->node); -} diff --git a/trunk/net/tipc/node_subscr.h b/trunk/net/tipc/node_subscr.h deleted file mode 100644 index a3b87ac4859b..000000000000 --- a/trunk/net/tipc/node_subscr.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * net/tipc/node_subscr.h: Include file for TIPC "node down" subscription handling - * - * Copyright (c) 1995-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_NODE_SUBSCR_H -#define _TIPC_NODE_SUBSCR_H - -#include "addr.h" - -typedef void (*net_ev_handler) (void *usr_handle); - -/** - * struct node_subscr - "node down" subscription entry - * @node: ptr to node structure of interest (or NULL, if none) - * @handle_node_down: routine to invoke when node fails - * @usr_handle: argument to pass to routine when node fails - * @nodesub_list: adjacent entries in list of subscriptions for the node - */ - -struct node_subscr { - struct node *node; - net_ev_handler handle_node_down; - void *usr_handle; - struct list_head nodesub_list; -}; - -void nodesub_subscribe(struct node_subscr *node_sub, u32 addr, - void *usr_handle, net_ev_handler handle_down); -void nodesub_unsubscribe(struct node_subscr *node_sub); - -#endif diff --git a/trunk/net/tipc/port.c b/trunk/net/tipc/port.c deleted file mode 100644 index 66caca7abe92..000000000000 --- a/trunk/net/tipc/port.c +++ /dev/null @@ -1,1708 +0,0 @@ -/* - * net/tipc/port.c: TIPC port code - * - * Copyright (c) 1992-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "config.h" -#include "dbg.h" -#include "port.h" -#include "addr.h" -#include "link.h" -#include "node.h" -#include "port.h" -#include "name_table.h" -#include "user_reg.h" -#include "msg.h" -#include "bcast.h" - -/* Connection management: */ -#define PROBING_INTERVAL 3600000 /* [ms] => 1 h */ -#define CONFIRMED 0 -#define PROBING 1 - -#define MAX_REJECT_SIZE 1024 - -static struct sk_buff *msg_queue_head = 0; -static struct sk_buff *msg_queue_tail = 0; - -spinlock_t port_list_lock = SPIN_LOCK_UNLOCKED; -static spinlock_t queue_lock = SPIN_LOCK_UNLOCKED; - -LIST_HEAD(ports); -static void port_handle_node_down(unsigned long ref); -static struct sk_buff* port_build_self_abort_msg(struct port *,u32 err); -static struct sk_buff* port_build_peer_abort_msg(struct port *,u32 err); -static void port_timeout(unsigned long ref); - - -static inline u32 port_peernode(struct port *p_ptr) -{ - return msg_destnode(&p_ptr->publ.phdr); -} - -static inline u32 port_peerport(struct port *p_ptr) -{ - return msg_destport(&p_ptr->publ.phdr); -} - -static inline u32 port_out_seqno(struct port *p_ptr) -{ - return msg_transp_seqno(&p_ptr->publ.phdr); -} - -static inline void port_set_out_seqno(struct port *p_ptr, u32 seqno) -{ - msg_set_transp_seqno(&p_ptr->publ.phdr,seqno); -} - -static inline void port_incr_out_seqno(struct port *p_ptr) -{ - struct tipc_msg *m = &p_ptr->publ.phdr; - - if (likely(!msg_routed(m))) - return; - msg_set_transp_seqno(m, (msg_transp_seqno(m) + 1)); -} - -/** - * tipc_multicast - send a multicast message to local and remote destinations - */ - -int tipc_multicast(u32 ref, struct tipc_name_seq const *seq, u32 domain, - u32 num_sect, struct iovec const *msg_sect) -{ - struct tipc_msg *hdr; - struct sk_buff *buf; - struct sk_buff *ibuf = NULL; - struct port_list dports = {0, NULL, }; - struct port *oport = port_deref(ref); - int ext_targets; - int res; - - if (unlikely(!oport)) - return -EINVAL; - - /* Create multicast message */ - - hdr = &oport->publ.phdr; - msg_set_type(hdr, TIPC_MCAST_MSG); - msg_set_nametype(hdr, seq->type); - msg_set_namelower(hdr, seq->lower); - msg_set_nameupper(hdr, seq->upper); - msg_set_hdr_sz(hdr, MCAST_H_SIZE); - res = msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, - !oport->user_port, &buf); - if (unlikely(!buf)) - return res; - - /* Figure out where to send multicast message */ - - ext_targets = nametbl_mc_translate(seq->type, seq->lower, seq->upper, - TIPC_NODE_SCOPE, &dports); - - /* Send message to destinations (duplicate it only if necessary) */ - - if (ext_targets) { - if (dports.count != 0) { - ibuf = skb_copy(buf, GFP_ATOMIC); - if (ibuf == NULL) { - port_list_free(&dports); - buf_discard(buf); - return -ENOMEM; - } - } - res = bclink_send_msg(buf); - if ((res < 0) && (dports.count != 0)) { - buf_discard(ibuf); - } - } else { - ibuf = buf; - } - - if (res >= 0) { - if (ibuf) - port_recv_mcast(ibuf, &dports); - } else { - port_list_free(&dports); - } - return res; -} - -/** - * port_recv_mcast - deliver multicast message to all destination ports - * - * If there is no port list, perform a lookup to create one - */ - -void port_recv_mcast(struct sk_buff *buf, struct port_list *dp) -{ - struct tipc_msg* msg; - struct port_list dports = {0, NULL, }; - struct port_list *item = dp; - int cnt = 0; - - assert(buf); - msg = buf_msg(buf); - - /* Create destination port list, if one wasn't supplied */ - - if (dp == NULL) { - nametbl_mc_translate(msg_nametype(msg), - msg_namelower(msg), - msg_nameupper(msg), - TIPC_CLUSTER_SCOPE, - &dports); - item = dp = &dports; - } - - /* Deliver a copy of message to each destination port */ - - if (dp->count != 0) { - if (dp->count == 1) { - msg_set_destport(msg, dp->ports[0]); - port_recv_msg(buf); - port_list_free(dp); - return; - } - for (; cnt < dp->count; cnt++) { - int index = cnt % PLSIZE; - struct sk_buff *b = skb_clone(buf, GFP_ATOMIC); - - if (b == NULL) { - warn("Buffer allocation failure\n"); - msg_dbg(msg, "LOST:"); - goto exit; - } - if ((index == 0) && (cnt != 0)) { - item = item->next; - } - msg_set_destport(buf_msg(b),item->ports[index]); - port_recv_msg(b); - } - } -exit: - buf_discard(buf); - port_list_free(dp); -} - -/** - * tipc_createport_raw - create a native TIPC port - * - * Returns local port reference - */ - -u32 tipc_createport_raw(void *usr_handle, - u32 (*dispatcher)(struct tipc_port *, struct sk_buff *), - void (*wakeup)(struct tipc_port *), - const u32 importance) -{ - struct port *p_ptr; - struct tipc_msg *msg; - u32 ref; - - p_ptr = kmalloc(sizeof(*p_ptr), GFP_ATOMIC); - if (p_ptr == NULL) { - warn("Memory squeeze; failed to create port\n"); - return 0; - } - memset(p_ptr, 0, sizeof(*p_ptr)); - ref = ref_acquire(p_ptr, &p_ptr->publ.lock); - if (!ref) { - warn("Reference Table Exhausted\n"); - kfree(p_ptr); - return 0; - } - - port_lock(ref); - p_ptr->publ.ref = ref; - msg = &p_ptr->publ.phdr; - msg_init(msg, DATA_LOW, TIPC_NAMED_MSG, TIPC_OK, LONG_H_SIZE, 0); - msg_set_orignode(msg, tipc_own_addr); - msg_set_prevnode(msg, tipc_own_addr); - msg_set_origport(msg, ref); - msg_set_importance(msg,importance); - p_ptr->last_in_seqno = 41; - p_ptr->sent = 1; - p_ptr->publ.usr_handle = usr_handle; - INIT_LIST_HEAD(&p_ptr->wait_list); - INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); - p_ptr->congested_link = 0; - p_ptr->max_pkt = MAX_PKT_DEFAULT; - p_ptr->dispatcher = dispatcher; - p_ptr->wakeup = wakeup; - p_ptr->user_port = 0; - k_init_timer(&p_ptr->timer, (Handler)port_timeout, ref); - spin_lock_bh(&port_list_lock); - INIT_LIST_HEAD(&p_ptr->publications); - INIT_LIST_HEAD(&p_ptr->port_list); - list_add_tail(&p_ptr->port_list, &ports); - spin_unlock_bh(&port_list_lock); - port_unlock(p_ptr); - return ref; -} - -int tipc_deleteport(u32 ref) -{ - struct port *p_ptr; - struct sk_buff *buf = 0; - - tipc_withdraw(ref, 0, 0); - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - - ref_discard(ref); - port_unlock(p_ptr); - - k_cancel_timer(&p_ptr->timer); - if (p_ptr->publ.connected) { - buf = port_build_peer_abort_msg(p_ptr, TIPC_ERR_NO_PORT); - nodesub_unsubscribe(&p_ptr->subscription); - } - if (p_ptr->user_port) { - reg_remove_port(p_ptr->user_port); - kfree(p_ptr->user_port); - } - - spin_lock_bh(&port_list_lock); - list_del(&p_ptr->port_list); - list_del(&p_ptr->wait_list); - spin_unlock_bh(&port_list_lock); - k_term_timer(&p_ptr->timer); - kfree(p_ptr); - dbg("Deleted port %u\n", ref); - net_route_msg(buf); - return TIPC_OK; -} - -/** - * tipc_get_port() - return port associated with 'ref' - * - * Note: Port is not locked. - */ - -struct tipc_port *tipc_get_port(const u32 ref) -{ - return (struct tipc_port *)ref_deref(ref); -} - -/** - * tipc_get_handle - return user handle associated to port 'ref' - */ - -void *tipc_get_handle(const u32 ref) -{ - struct port *p_ptr; - void * handle; - - p_ptr = port_lock(ref); - if (!p_ptr) - return 0; - handle = p_ptr->publ.usr_handle; - port_unlock(p_ptr); - return handle; -} - -static inline int port_unreliable(struct port *p_ptr) -{ - return msg_src_droppable(&p_ptr->publ.phdr); -} - -int tipc_portunreliable(u32 ref, unsigned int *isunreliable) -{ - struct port *p_ptr; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - *isunreliable = port_unreliable(p_ptr); - spin_unlock_bh(p_ptr->publ.lock); - return TIPC_OK; -} - -int tipc_set_portunreliable(u32 ref, unsigned int isunreliable) -{ - struct port *p_ptr; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - msg_set_src_droppable(&p_ptr->publ.phdr, (isunreliable != 0)); - port_unlock(p_ptr); - return TIPC_OK; -} - -static inline int port_unreturnable(struct port *p_ptr) -{ - return msg_dest_droppable(&p_ptr->publ.phdr); -} - -int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable) -{ - struct port *p_ptr; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - *isunrejectable = port_unreturnable(p_ptr); - spin_unlock_bh(p_ptr->publ.lock); - return TIPC_OK; -} - -int tipc_set_portunreturnable(u32 ref, unsigned int isunrejectable) -{ - struct port *p_ptr; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - msg_set_dest_droppable(&p_ptr->publ.phdr, (isunrejectable != 0)); - port_unlock(p_ptr); - return TIPC_OK; -} - -/* - * port_build_proto_msg(): build a port level protocol - * or a connection abortion message. Called with - * tipc_port lock on. - */ -static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, - u32 origport, u32 orignode, - u32 usr, u32 type, u32 err, - u32 seqno, u32 ack) -{ - struct sk_buff *buf; - struct tipc_msg *msg; - - buf = buf_acquire(LONG_H_SIZE); - if (buf) { - msg = buf_msg(buf); - msg_init(msg, usr, type, err, LONG_H_SIZE, destnode); - msg_set_destport(msg, destport); - msg_set_origport(msg, origport); - msg_set_destnode(msg, destnode); - msg_set_orignode(msg, orignode); - msg_set_transp_seqno(msg, seqno); - msg_set_msgcnt(msg, ack); - msg_dbg(msg, "PORT>SEND>:"); - } - return buf; -} - -int tipc_set_msg_option(struct tipc_port *tp_ptr, const char *opt, const u32 sz) -{ - msg_expand(&tp_ptr->phdr, msg_destnode(&tp_ptr->phdr)); - msg_set_options(&tp_ptr->phdr, opt, sz); - return TIPC_OK; -} - -int tipc_reject_msg(struct sk_buff *buf, u32 err) -{ - struct tipc_msg *msg = buf_msg(buf); - struct sk_buff *rbuf; - struct tipc_msg *rmsg; - int hdr_sz; - u32 imp = msg_importance(msg); - u32 data_sz = msg_data_sz(msg); - - if (data_sz > MAX_REJECT_SIZE) - data_sz = MAX_REJECT_SIZE; - if (msg_connected(msg) && (imp < TIPC_CRITICAL_IMPORTANCE)) - imp++; - msg_dbg(msg, "port->rej: "); - - /* discard rejected message if it shouldn't be returned to sender */ - if (msg_errcode(msg) || msg_dest_droppable(msg)) { - buf_discard(buf); - return data_sz; - } - - /* construct rejected message */ - if (msg_mcast(msg)) - hdr_sz = MCAST_H_SIZE; - else - hdr_sz = LONG_H_SIZE; - rbuf = buf_acquire(data_sz + hdr_sz); - if (rbuf == NULL) { - buf_discard(buf); - return data_sz; - } - rmsg = buf_msg(rbuf); - msg_init(rmsg, imp, msg_type(msg), err, hdr_sz, msg_orignode(msg)); - msg_set_destport(rmsg, msg_origport(msg)); - msg_set_prevnode(rmsg, tipc_own_addr); - msg_set_origport(rmsg, msg_destport(msg)); - if (msg_short(msg)) - msg_set_orignode(rmsg, tipc_own_addr); - else - msg_set_orignode(rmsg, msg_destnode(msg)); - msg_set_size(rmsg, data_sz + hdr_sz); - msg_set_nametype(rmsg, msg_nametype(msg)); - msg_set_nameinst(rmsg, msg_nameinst(msg)); - memcpy(rbuf->data + hdr_sz, msg_data(msg), data_sz); - - /* send self-abort message when rejecting on a connected port */ - if (msg_connected(msg)) { - struct sk_buff *abuf = 0; - struct port *p_ptr = port_lock(msg_destport(msg)); - - if (p_ptr) { - if (p_ptr->publ.connected) - abuf = port_build_self_abort_msg(p_ptr, err); - port_unlock(p_ptr); - } - net_route_msg(abuf); - } - - /* send rejected message */ - buf_discard(buf); - net_route_msg(rbuf); - return data_sz; -} - -int port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, - struct iovec const *msg_sect, u32 num_sect, - int err) -{ - struct sk_buff *buf; - int res; - - res = msg_build(hdr, msg_sect, num_sect, MAX_MSG_SIZE, - !p_ptr->user_port, &buf); - if (!buf) - return res; - - return tipc_reject_msg(buf, err); -} - -static void port_timeout(unsigned long ref) -{ - struct port *p_ptr = port_lock(ref); - struct sk_buff *buf = 0; - - if (!p_ptr || !p_ptr->publ.connected) - return; - - /* Last probe answered ? */ - if (p_ptr->probing_state == PROBING) { - buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_PORT); - } else { - buf = port_build_proto_msg(port_peerport(p_ptr), - port_peernode(p_ptr), - p_ptr->publ.ref, - tipc_own_addr, - CONN_MANAGER, - CONN_PROBE, - TIPC_OK, - port_out_seqno(p_ptr), - 0); - port_incr_out_seqno(p_ptr); - p_ptr->probing_state = PROBING; - k_start_timer(&p_ptr->timer, p_ptr->probing_interval); - } - port_unlock(p_ptr); - net_route_msg(buf); -} - - -static void port_handle_node_down(unsigned long ref) -{ - struct port *p_ptr = port_lock(ref); - struct sk_buff* buf = 0; - - if (!p_ptr) - return; - buf = port_build_self_abort_msg(p_ptr, TIPC_ERR_NO_NODE); - port_unlock(p_ptr); - net_route_msg(buf); -} - - -static struct sk_buff *port_build_self_abort_msg(struct port *p_ptr, u32 err) -{ - u32 imp = msg_importance(&p_ptr->publ.phdr); - - if (!p_ptr->publ.connected) - return 0; - if (imp < TIPC_CRITICAL_IMPORTANCE) - imp++; - return port_build_proto_msg(p_ptr->publ.ref, - tipc_own_addr, - port_peerport(p_ptr), - port_peernode(p_ptr), - imp, - TIPC_CONN_MSG, - err, - p_ptr->last_in_seqno + 1, - 0); -} - - -static struct sk_buff *port_build_peer_abort_msg(struct port *p_ptr, u32 err) -{ - u32 imp = msg_importance(&p_ptr->publ.phdr); - - if (!p_ptr->publ.connected) - return 0; - if (imp < TIPC_CRITICAL_IMPORTANCE) - imp++; - return port_build_proto_msg(port_peerport(p_ptr), - port_peernode(p_ptr), - p_ptr->publ.ref, - tipc_own_addr, - imp, - TIPC_CONN_MSG, - err, - port_out_seqno(p_ptr), - 0); -} - -void port_recv_proto_msg(struct sk_buff *buf) -{ - struct tipc_msg *msg = buf_msg(buf); - struct port *p_ptr = port_lock(msg_destport(msg)); - u32 err = TIPC_OK; - struct sk_buff *r_buf = 0; - struct sk_buff *abort_buf = 0; - - msg_dbg(msg, "PORTpubl.connected) { - if (port_peernode(p_ptr) != msg_orignode(msg)) - err = TIPC_ERR_NO_PORT; - if (port_peerport(p_ptr) != msg_origport(msg)) - err = TIPC_ERR_NO_PORT; - if (!err && msg_routed(msg)) { - u32 seqno = msg_transp_seqno(msg); - u32 myno = ++p_ptr->last_in_seqno; - if (seqno != myno) { - err = TIPC_ERR_NO_PORT; - abort_buf = port_build_self_abort_msg(p_ptr, err); - } - } - if (msg_type(msg) == CONN_ACK) { - int wakeup = port_congested(p_ptr) && - p_ptr->publ.congested && - p_ptr->wakeup; - p_ptr->acked += msg_msgcnt(msg); - if (port_congested(p_ptr)) - goto exit; - p_ptr->publ.congested = 0; - if (!wakeup) - goto exit; - p_ptr->wakeup(&p_ptr->publ); - goto exit; - } - } else if (p_ptr->publ.published) { - err = TIPC_ERR_NO_PORT; - } - if (err) { - r_buf = port_build_proto_msg(msg_origport(msg), - msg_orignode(msg), - msg_destport(msg), - tipc_own_addr, - DATA_HIGH, - TIPC_CONN_MSG, - err, - 0, - 0); - goto exit; - } - - /* All is fine */ - if (msg_type(msg) == CONN_PROBE) { - r_buf = port_build_proto_msg(msg_origport(msg), - msg_orignode(msg), - msg_destport(msg), - tipc_own_addr, - CONN_MANAGER, - CONN_PROBE_REPLY, - TIPC_OK, - port_out_seqno(p_ptr), - 0); - } - p_ptr->probing_state = CONFIRMED; - port_incr_out_seqno(p_ptr); -exit: - if (p_ptr) - port_unlock(p_ptr); - net_route_msg(r_buf); - net_route_msg(abort_buf); - buf_discard(buf); -} - -static void port_print(struct port *p_ptr, struct print_buf *buf, int full_id) -{ - struct publication *publ; - - if (full_id) - tipc_printf(buf, "<%u.%u.%u:%u>:", - tipc_zone(tipc_own_addr), tipc_cluster(tipc_own_addr), - tipc_node(tipc_own_addr), p_ptr->publ.ref); - else - tipc_printf(buf, "%-10u:", p_ptr->publ.ref); - - if (p_ptr->publ.connected) { - u32 dport = port_peerport(p_ptr); - u32 destnode = port_peernode(p_ptr); - - tipc_printf(buf, " connected to <%u.%u.%u:%u>", - tipc_zone(destnode), tipc_cluster(destnode), - tipc_node(destnode), dport); - if (p_ptr->publ.conn_type != 0) - tipc_printf(buf, " via {%u,%u}", - p_ptr->publ.conn_type, - p_ptr->publ.conn_instance); - } - else if (p_ptr->publ.published) { - tipc_printf(buf, " bound to"); - list_for_each_entry(publ, &p_ptr->publications, pport_list) { - if (publ->lower == publ->upper) - tipc_printf(buf, " {%u,%u}", publ->type, - publ->lower); - else - tipc_printf(buf, " {%u,%u,%u}", publ->type, - publ->lower, publ->upper); - } - } - tipc_printf(buf, "\n"); -} - -#define MAX_PORT_QUERY 32768 - -struct sk_buff *port_get_ports(void) -{ - struct sk_buff *buf; - struct tlv_desc *rep_tlv; - struct print_buf pb; - struct port *p_ptr; - int str_len; - - buf = cfg_reply_alloc(TLV_SPACE(MAX_PORT_QUERY)); - if (!buf) - return NULL; - rep_tlv = (struct tlv_desc *)buf->data; - - printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_QUERY); - spin_lock_bh(&port_list_lock); - list_for_each_entry(p_ptr, &ports, port_list) { - spin_lock_bh(p_ptr->publ.lock); - port_print(p_ptr, &pb, 0); - spin_unlock_bh(p_ptr->publ.lock); - } - spin_unlock_bh(&port_list_lock); - str_len = printbuf_validate(&pb); - - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - -#if 0 - -#define MAX_PORT_STATS 2000 - -struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space) -{ - u32 ref; - struct port *p_ptr; - struct sk_buff *buf; - struct tlv_desc *rep_tlv; - struct print_buf pb; - int str_len; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_PORT_REF)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - ref = *(u32 *)TLV_DATA(req_tlv_area); - ref = ntohl(ref); - - p_ptr = port_lock(ref); - if (!p_ptr) - return cfg_reply_error_string("port not found"); - - buf = cfg_reply_alloc(TLV_SPACE(MAX_PORT_STATS)); - if (!buf) { - port_unlock(p_ptr); - return NULL; - } - rep_tlv = (struct tlv_desc *)buf->data; - - printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_STATS); - port_print(p_ptr, &pb, 1); - /* NEED TO FILL IN ADDITIONAL PORT STATISTICS HERE */ - port_unlock(p_ptr); - str_len = printbuf_validate(&pb); - - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - -#endif - -void port_reinit(void) -{ - struct port *p_ptr; - struct tipc_msg *msg; - - spin_lock_bh(&port_list_lock); - list_for_each_entry(p_ptr, &ports, port_list) { - msg = &p_ptr->publ.phdr; - if (msg_orignode(msg) == tipc_own_addr) - break; - msg_set_orignode(msg, tipc_own_addr); - } - spin_unlock_bh(&port_list_lock); -} - - -/* - * port_dispatcher_sigh(): Signal handler for messages destinated - * to the tipc_port interface. - */ - -static void port_dispatcher_sigh(void *dummy) -{ - struct sk_buff *buf; - - spin_lock_bh(&queue_lock); - buf = msg_queue_head; - msg_queue_head = 0; - spin_unlock_bh(&queue_lock); - - while (buf) { - struct port *p_ptr; - struct user_port *up_ptr; - struct tipc_portid orig; - struct tipc_name_seq dseq; - void *usr_handle; - int connected; - int published; - - struct sk_buff *next = buf->next; - struct tipc_msg *msg = buf_msg(buf); - u32 dref = msg_destport(msg); - - p_ptr = port_lock(dref); - if (!p_ptr) { - /* Port deleted while msg in queue */ - tipc_reject_msg(buf, TIPC_ERR_NO_PORT); - buf = next; - continue; - } - orig.ref = msg_origport(msg); - orig.node = msg_orignode(msg); - up_ptr = p_ptr->user_port; - usr_handle = up_ptr->usr_handle; - connected = p_ptr->publ.connected; - published = p_ptr->publ.published; - - if (unlikely(msg_errcode(msg))) - goto err; - - switch (msg_type(msg)) { - - case TIPC_CONN_MSG:{ - tipc_conn_msg_event cb = up_ptr->conn_msg_cb; - u32 peer_port = port_peerport(p_ptr); - u32 peer_node = port_peernode(p_ptr); - - spin_unlock_bh(p_ptr->publ.lock); - if (unlikely(!connected)) { - if (unlikely(published)) - goto reject; - tipc_connect2port(dref,&orig); - } - if (unlikely(msg_origport(msg) != peer_port)) - goto reject; - if (unlikely(msg_orignode(msg) != peer_node)) - goto reject; - if (unlikely(!cb)) - goto reject; - if (unlikely(++p_ptr->publ.conn_unacked >= - TIPC_FLOW_CONTROL_WIN)) - tipc_acknowledge(dref, - p_ptr->publ.conn_unacked); - skb_pull(buf, msg_hdr_sz(msg)); - cb(usr_handle, dref, &buf, msg_data(msg), - msg_data_sz(msg)); - break; - } - case TIPC_DIRECT_MSG:{ - tipc_msg_event cb = up_ptr->msg_cb; - - spin_unlock_bh(p_ptr->publ.lock); - if (unlikely(connected)) - goto reject; - if (unlikely(!cb)) - goto reject; - skb_pull(buf, msg_hdr_sz(msg)); - cb(usr_handle, dref, &buf, msg_data(msg), - msg_data_sz(msg), msg_importance(msg), - &orig); - break; - } - case TIPC_NAMED_MSG:{ - tipc_named_msg_event cb = up_ptr->named_msg_cb; - - spin_unlock_bh(p_ptr->publ.lock); - if (unlikely(connected)) - goto reject; - if (unlikely(!cb)) - goto reject; - if (unlikely(!published)) - goto reject; - dseq.type = msg_nametype(msg); - dseq.lower = msg_nameinst(msg); - dseq.upper = dseq.lower; - skb_pull(buf, msg_hdr_sz(msg)); - cb(usr_handle, dref, &buf, msg_data(msg), - msg_data_sz(msg), msg_importance(msg), - &orig, &dseq); - break; - } - } - if (buf) - buf_discard(buf); - buf = next; - continue; -err: - switch (msg_type(msg)) { - - case TIPC_CONN_MSG:{ - tipc_conn_shutdown_event cb = - up_ptr->conn_err_cb; - u32 peer_port = port_peerport(p_ptr); - u32 peer_node = port_peernode(p_ptr); - - spin_unlock_bh(p_ptr->publ.lock); - if (!connected || !cb) - break; - if (msg_origport(msg) != peer_port) - break; - if (msg_orignode(msg) != peer_node) - break; - tipc_disconnect(dref); - skb_pull(buf, msg_hdr_sz(msg)); - cb(usr_handle, dref, &buf, msg_data(msg), - msg_data_sz(msg), msg_errcode(msg)); - break; - } - case TIPC_DIRECT_MSG:{ - tipc_msg_err_event cb = up_ptr->err_cb; - - spin_unlock_bh(p_ptr->publ.lock); - if (connected || !cb) - break; - skb_pull(buf, msg_hdr_sz(msg)); - cb(usr_handle, dref, &buf, msg_data(msg), - msg_data_sz(msg), msg_errcode(msg), &orig); - break; - } - case TIPC_NAMED_MSG:{ - tipc_named_msg_err_event cb = - up_ptr->named_err_cb; - - spin_unlock_bh(p_ptr->publ.lock); - if (connected || !cb) - break; - dseq.type = msg_nametype(msg); - dseq.lower = msg_nameinst(msg); - dseq.upper = dseq.lower; - skb_pull(buf, msg_hdr_sz(msg)); - cb(usr_handle, dref, &buf, msg_data(msg), - msg_data_sz(msg), msg_errcode(msg), &dseq); - break; - } - } - if (buf) - buf_discard(buf); - buf = next; - continue; -reject: - tipc_reject_msg(buf, TIPC_ERR_NO_PORT); - buf = next; - } -} - -/* - * port_dispatcher(): Dispatcher for messages destinated - * to the tipc_port interface. Called with port locked. - */ - -static u32 port_dispatcher(struct tipc_port *dummy, struct sk_buff *buf) -{ - buf->next = NULL; - spin_lock_bh(&queue_lock); - if (msg_queue_head) { - msg_queue_tail->next = buf; - msg_queue_tail = buf; - } else { - msg_queue_tail = msg_queue_head = buf; - k_signal((Handler)port_dispatcher_sigh, 0); - } - spin_unlock_bh(&queue_lock); - return TIPC_OK; -} - -/* - * Wake up port after congestion: Called with port locked, - * - */ - -static void port_wakeup_sh(unsigned long ref) -{ - struct port *p_ptr; - struct user_port *up_ptr; - tipc_continue_event cb = 0; - void *uh = 0; - - p_ptr = port_lock(ref); - if (p_ptr) { - up_ptr = p_ptr->user_port; - if (up_ptr) { - cb = up_ptr->continue_event_cb; - uh = up_ptr->usr_handle; - } - port_unlock(p_ptr); - } - if (cb) - cb(uh, ref); -} - - -static void port_wakeup(struct tipc_port *p_ptr) -{ - k_signal((Handler)port_wakeup_sh, p_ptr->ref); -} - -void tipc_acknowledge(u32 ref, u32 ack) -{ - struct port *p_ptr; - struct sk_buff *buf = 0; - - p_ptr = port_lock(ref); - if (!p_ptr) - return; - if (p_ptr->publ.connected) { - p_ptr->publ.conn_unacked -= ack; - buf = port_build_proto_msg(port_peerport(p_ptr), - port_peernode(p_ptr), - ref, - tipc_own_addr, - CONN_MANAGER, - CONN_ACK, - TIPC_OK, - port_out_seqno(p_ptr), - ack); - } - port_unlock(p_ptr); - net_route_msg(buf); -} - -/* - * tipc_createport(): user level call. Will add port to - * registry if non-zero user_ref. - */ - -int tipc_createport(u32 user_ref, - void *usr_handle, - unsigned int importance, - tipc_msg_err_event error_cb, - tipc_named_msg_err_event named_error_cb, - tipc_conn_shutdown_event conn_error_cb, - tipc_msg_event msg_cb, - tipc_named_msg_event named_msg_cb, - tipc_conn_msg_event conn_msg_cb, - tipc_continue_event continue_event_cb,/* May be zero */ - u32 *portref) -{ - struct user_port *up_ptr; - struct port *p_ptr; - u32 ref; - - up_ptr = (struct user_port *)kmalloc(sizeof(*up_ptr), GFP_ATOMIC); - if (up_ptr == NULL) { - return -ENOMEM; - } - ref = tipc_createport_raw(0, port_dispatcher, port_wakeup, importance); - p_ptr = port_lock(ref); - if (!p_ptr) { - kfree(up_ptr); - return -ENOMEM; - } - - p_ptr->user_port = up_ptr; - up_ptr->user_ref = user_ref; - up_ptr->usr_handle = usr_handle; - up_ptr->ref = p_ptr->publ.ref; - up_ptr->err_cb = error_cb; - up_ptr->named_err_cb = named_error_cb; - up_ptr->conn_err_cb = conn_error_cb; - up_ptr->msg_cb = msg_cb; - up_ptr->named_msg_cb = named_msg_cb; - up_ptr->conn_msg_cb = conn_msg_cb; - up_ptr->continue_event_cb = continue_event_cb; - INIT_LIST_HEAD(&up_ptr->uport_list); - reg_add_port(up_ptr); - *portref = p_ptr->publ.ref; - dbg(" tipc_createport: %x with ref %u\n", p_ptr, p_ptr->publ.ref); - port_unlock(p_ptr); - return TIPC_OK; -} - -int tipc_ownidentity(u32 ref, struct tipc_portid *id) -{ - id->ref = ref; - id->node = tipc_own_addr; - return TIPC_OK; -} - -int tipc_portimportance(u32 ref, unsigned int *importance) -{ - struct port *p_ptr; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr); - spin_unlock_bh(p_ptr->publ.lock); - return TIPC_OK; -} - -int tipc_set_portimportance(u32 ref, unsigned int imp) -{ - struct port *p_ptr; - - if (imp > TIPC_CRITICAL_IMPORTANCE) - return -EINVAL; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - msg_set_importance(&p_ptr->publ.phdr, (u32)imp); - spin_unlock_bh(p_ptr->publ.lock); - return TIPC_OK; -} - - -int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) -{ - struct port *p_ptr; - struct publication *publ; - u32 key; - int res = -EINVAL; - - p_ptr = port_lock(ref); - dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, " - "lower = %u, upper = %u\n", - ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper); - if (!p_ptr) - return -EINVAL; - if (p_ptr->publ.connected) - goto exit; - if (seq->lower > seq->upper) - goto exit; - if ((scope < TIPC_ZONE_SCOPE) || (scope > TIPC_NODE_SCOPE)) - goto exit; - key = ref + p_ptr->pub_count + 1; - if (key == ref) { - res = -EADDRINUSE; - goto exit; - } - publ = nametbl_publish(seq->type, seq->lower, seq->upper, - scope, p_ptr->publ.ref, key); - if (publ) { - list_add(&publ->pport_list, &p_ptr->publications); - p_ptr->pub_count++; - p_ptr->publ.published = 1; - res = TIPC_OK; - } -exit: - port_unlock(p_ptr); - return res; -} - -int tipc_withdraw(u32 ref, unsigned int scope, struct tipc_name_seq const *seq) -{ - struct port *p_ptr; - struct publication *publ; - struct publication *tpubl; - int res = -EINVAL; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - if (!p_ptr->publ.published) - goto exit; - if (!seq) { - list_for_each_entry_safe(publ, tpubl, - &p_ptr->publications, pport_list) { - nametbl_withdraw(publ->type, publ->lower, - publ->ref, publ->key); - } - res = TIPC_OK; - } else { - list_for_each_entry_safe(publ, tpubl, - &p_ptr->publications, pport_list) { - if (publ->scope != scope) - continue; - if (publ->type != seq->type) - continue; - if (publ->lower != seq->lower) - continue; - if (publ->upper != seq->upper) - break; - nametbl_withdraw(publ->type, publ->lower, - publ->ref, publ->key); - res = TIPC_OK; - break; - } - } - if (list_empty(&p_ptr->publications)) - p_ptr->publ.published = 0; -exit: - port_unlock(p_ptr); - return res; -} - -int tipc_connect2port(u32 ref, struct tipc_portid const *peer) -{ - struct port *p_ptr; - struct tipc_msg *msg; - int res = -EINVAL; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - if (p_ptr->publ.published || p_ptr->publ.connected) - goto exit; - if (!peer->ref) - goto exit; - - msg = &p_ptr->publ.phdr; - msg_set_destnode(msg, peer->node); - msg_set_destport(msg, peer->ref); - msg_set_orignode(msg, tipc_own_addr); - msg_set_origport(msg, p_ptr->publ.ref); - msg_set_transp_seqno(msg, 42); - msg_set_type(msg, TIPC_CONN_MSG); - if (!may_route(peer->node)) - msg_set_hdr_sz(msg, SHORT_H_SIZE); - else - msg_set_hdr_sz(msg, LONG_H_SIZE); - - p_ptr->probing_interval = PROBING_INTERVAL; - p_ptr->probing_state = CONFIRMED; - p_ptr->publ.connected = 1; - k_start_timer(&p_ptr->timer, p_ptr->probing_interval); - - nodesub_subscribe(&p_ptr->subscription,peer->node, - (void *)(unsigned long)ref, - (net_ev_handler)port_handle_node_down); - res = TIPC_OK; -exit: - port_unlock(p_ptr); - p_ptr->max_pkt = link_get_max_pkt(peer->node, ref); - return res; -} - -/* - * tipc_disconnect(): Disconnect port form peer. - * This is a node local operation. - */ - -int tipc_disconnect(u32 ref) -{ - struct port *p_ptr; - int res = -ENOTCONN; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - if (p_ptr->publ.connected) { - p_ptr->publ.connected = 0; - /* let timer expire on it's own to avoid deadlock! */ - nodesub_unsubscribe(&p_ptr->subscription); - res = TIPC_OK; - } - port_unlock(p_ptr); - return res; -} - -/* - * tipc_shutdown(): Send a SHUTDOWN msg to peer and disconnect - */ -int tipc_shutdown(u32 ref) -{ - struct port *p_ptr; - struct sk_buff *buf = 0; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - - if (p_ptr->publ.connected) { - u32 imp = msg_importance(&p_ptr->publ.phdr); - if (imp < TIPC_CRITICAL_IMPORTANCE) - imp++; - buf = port_build_proto_msg(port_peerport(p_ptr), - port_peernode(p_ptr), - ref, - tipc_own_addr, - imp, - TIPC_CONN_MSG, - TIPC_CONN_SHUTDOWN, - port_out_seqno(p_ptr), - 0); - } - port_unlock(p_ptr); - net_route_msg(buf); - return tipc_disconnect(ref); -} - -int tipc_isconnected(u32 ref, int *isconnected) -{ - struct port *p_ptr; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - *isconnected = p_ptr->publ.connected; - port_unlock(p_ptr); - return TIPC_OK; -} - -int tipc_peer(u32 ref, struct tipc_portid *peer) -{ - struct port *p_ptr; - int res; - - p_ptr = port_lock(ref); - if (!p_ptr) - return -EINVAL; - if (p_ptr->publ.connected) { - peer->ref = port_peerport(p_ptr); - peer->node = port_peernode(p_ptr); - res = TIPC_OK; - } else - res = -ENOTCONN; - port_unlock(p_ptr); - return res; -} - -int tipc_ref_valid(u32 ref) -{ - /* Works irrespective of type */ - return !!ref_deref(ref); -} - - -/* - * port_recv_sections(): Concatenate and deliver sectioned - * message for this node. - */ - -int port_recv_sections(struct port *sender, unsigned int num_sect, - struct iovec const *msg_sect) -{ - struct sk_buff *buf; - int res; - - res = msg_build(&sender->publ.phdr, msg_sect, num_sect, - MAX_MSG_SIZE, !sender->user_port, &buf); - if (likely(buf)) - port_recv_msg(buf); - return res; -} - -/** - * tipc_send - send message sections on connection - */ - -int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) -{ - struct port *p_ptr; - u32 destnode; - int res; - - p_ptr = port_deref(ref); - if (!p_ptr || !p_ptr->publ.connected) - return -EINVAL; - - p_ptr->publ.congested = 1; - if (!port_congested(p_ptr)) { - destnode = port_peernode(p_ptr); - if (likely(destnode != tipc_own_addr)) - res = link_send_sections_fast(p_ptr, msg_sect, num_sect, - destnode); - else - res = port_recv_sections(p_ptr, num_sect, msg_sect); - - if (likely(res != -ELINKCONG)) { - port_incr_out_seqno(p_ptr); - p_ptr->publ.congested = 0; - p_ptr->sent++; - return res; - } - } - if (port_unreliable(p_ptr)) { - p_ptr->publ.congested = 0; - /* Just calculate msg length and return */ - return msg_calc_data_size(msg_sect, num_sect); - } - return -ELINKCONG; -} - -/** - * tipc_send_buf - send message buffer on connection - */ - -int tipc_send_buf(u32 ref, struct sk_buff *buf, unsigned int dsz) -{ - struct port *p_ptr; - struct tipc_msg *msg; - u32 destnode; - u32 hsz; - u32 sz; - u32 res; - - p_ptr = port_deref(ref); - if (!p_ptr || !p_ptr->publ.connected) - return -EINVAL; - - msg = &p_ptr->publ.phdr; - hsz = msg_hdr_sz(msg); - sz = hsz + dsz; - msg_set_size(msg, sz); - if (skb_cow(buf, hsz)) - return -ENOMEM; - - skb_push(buf, hsz); - memcpy(buf->data, (unchar *)msg, hsz); - destnode = msg_destnode(msg); - p_ptr->publ.congested = 1; - if (!port_congested(p_ptr)) { - if (likely(destnode != tipc_own_addr)) - res = tipc_send_buf_fast(buf, destnode); - else { - port_recv_msg(buf); - res = sz; - } - if (likely(res != -ELINKCONG)) { - port_incr_out_seqno(p_ptr); - p_ptr->sent++; - p_ptr->publ.congested = 0; - return res; - } - } - if (port_unreliable(p_ptr)) { - p_ptr->publ.congested = 0; - return dsz; - } - return -ELINKCONG; -} - -/** - * tipc_forward2name - forward message sections to port name - */ - -int tipc_forward2name(u32 ref, - struct tipc_name const *name, - u32 domain, - u32 num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *orig, - unsigned int importance) -{ - struct port *p_ptr; - struct tipc_msg *msg; - u32 destnode = domain; - u32 destport = 0; - int res; - - p_ptr = port_deref(ref); - if (!p_ptr || p_ptr->publ.connected) - return -EINVAL; - - msg = &p_ptr->publ.phdr; - msg_set_type(msg, TIPC_NAMED_MSG); - msg_set_orignode(msg, orig->node); - msg_set_origport(msg, orig->ref); - msg_set_hdr_sz(msg, LONG_H_SIZE); - msg_set_nametype(msg, name->type); - msg_set_nameinst(msg, name->instance); - msg_set_lookup_scope(msg, addr_scope(domain)); - if (importance <= TIPC_CRITICAL_IMPORTANCE) - msg_set_importance(msg,importance); - destport = nametbl_translate(name->type, name->instance, &destnode); - msg_set_destnode(msg, destnode); - msg_set_destport(msg, destport); - - if (likely(destport || destnode)) { - p_ptr->sent++; - if (likely(destnode == tipc_own_addr)) - return port_recv_sections(p_ptr, num_sect, msg_sect); - res = link_send_sections_fast(p_ptr, msg_sect, num_sect, - destnode); - if (likely(res != -ELINKCONG)) - return res; - if (port_unreliable(p_ptr)) { - /* Just calculate msg length and return */ - return msg_calc_data_size(msg_sect, num_sect); - } - return -ELINKCONG; - } - return port_reject_sections(p_ptr, msg, msg_sect, num_sect, - TIPC_ERR_NO_NAME); -} - -/** - * tipc_send2name - send message sections to port name - */ - -int tipc_send2name(u32 ref, - struct tipc_name const *name, - unsigned int domain, - unsigned int num_sect, - struct iovec const *msg_sect) -{ - struct tipc_portid orig; - - orig.ref = ref; - orig.node = tipc_own_addr; - return tipc_forward2name(ref, name, domain, num_sect, msg_sect, &orig, - TIPC_PORT_IMPORTANCE); -} - -/** - * tipc_forward_buf2name - forward message buffer to port name - */ - -int tipc_forward_buf2name(u32 ref, - struct tipc_name const *name, - u32 domain, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance) -{ - struct port *p_ptr; - struct tipc_msg *msg; - u32 destnode = domain; - u32 destport = 0; - int res; - - p_ptr = (struct port *)ref_deref(ref); - if (!p_ptr || p_ptr->publ.connected) - return -EINVAL; - - msg = &p_ptr->publ.phdr; - if (importance <= TIPC_CRITICAL_IMPORTANCE) - msg_set_importance(msg, importance); - msg_set_type(msg, TIPC_NAMED_MSG); - msg_set_orignode(msg, orig->node); - msg_set_origport(msg, orig->ref); - msg_set_nametype(msg, name->type); - msg_set_nameinst(msg, name->instance); - msg_set_lookup_scope(msg, addr_scope(domain)); - msg_set_hdr_sz(msg, LONG_H_SIZE); - msg_set_size(msg, LONG_H_SIZE + dsz); - destport = nametbl_translate(name->type, name->instance, &destnode); - msg_set_destnode(msg, destnode); - msg_set_destport(msg, destport); - msg_dbg(msg, "forw2name ==> "); - if (skb_cow(buf, LONG_H_SIZE)) - return -ENOMEM; - skb_push(buf, LONG_H_SIZE); - memcpy(buf->data, (unchar *)msg, LONG_H_SIZE); - msg_dbg(buf_msg(buf),"PREP:"); - if (likely(destport || destnode)) { - p_ptr->sent++; - if (destnode == tipc_own_addr) - return port_recv_msg(buf); - res = tipc_send_buf_fast(buf, destnode); - if (likely(res != -ELINKCONG)) - return res; - if (port_unreliable(p_ptr)) - return dsz; - return -ELINKCONG; - } - return tipc_reject_msg(buf, TIPC_ERR_NO_NAME); -} - -/** - * tipc_send_buf2name - send message buffer to port name - */ - -int tipc_send_buf2name(u32 ref, - struct tipc_name const *dest, - u32 domain, - struct sk_buff *buf, - unsigned int dsz) -{ - struct tipc_portid orig; - - orig.ref = ref; - orig.node = tipc_own_addr; - return tipc_forward_buf2name(ref, dest, domain, buf, dsz, &orig, - TIPC_PORT_IMPORTANCE); -} - -/** - * tipc_forward2port - forward message sections to port identity - */ - -int tipc_forward2port(u32 ref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *orig, - unsigned int importance) -{ - struct port *p_ptr; - struct tipc_msg *msg; - int res; - - p_ptr = port_deref(ref); - if (!p_ptr || p_ptr->publ.connected) - return -EINVAL; - - msg = &p_ptr->publ.phdr; - msg_set_type(msg, TIPC_DIRECT_MSG); - msg_set_orignode(msg, orig->node); - msg_set_origport(msg, orig->ref); - msg_set_destnode(msg, dest->node); - msg_set_destport(msg, dest->ref); - msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); - if (importance <= TIPC_CRITICAL_IMPORTANCE) - msg_set_importance(msg, importance); - p_ptr->sent++; - if (dest->node == tipc_own_addr) - return port_recv_sections(p_ptr, num_sect, msg_sect); - res = link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node); - if (likely(res != -ELINKCONG)) - return res; - if (port_unreliable(p_ptr)) { - /* Just calculate msg length and return */ - return msg_calc_data_size(msg_sect, num_sect); - } - return -ELINKCONG; -} - -/** - * tipc_send2port - send message sections to port identity - */ - -int tipc_send2port(u32 ref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect) -{ - struct tipc_portid orig; - - orig.ref = ref; - orig.node = tipc_own_addr; - return tipc_forward2port(ref, dest, num_sect, msg_sect, &orig, - TIPC_PORT_IMPORTANCE); -} - -/** - * tipc_forward_buf2port - forward message buffer to port identity - */ -int tipc_forward_buf2port(u32 ref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance) -{ - struct port *p_ptr; - struct tipc_msg *msg; - int res; - - p_ptr = (struct port *)ref_deref(ref); - if (!p_ptr || p_ptr->publ.connected) - return -EINVAL; - - msg = &p_ptr->publ.phdr; - msg_set_type(msg, TIPC_DIRECT_MSG); - msg_set_orignode(msg, orig->node); - msg_set_origport(msg, orig->ref); - msg_set_destnode(msg, dest->node); - msg_set_destport(msg, dest->ref); - msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); - if (importance <= TIPC_CRITICAL_IMPORTANCE) - msg_set_importance(msg, importance); - msg_set_size(msg, DIR_MSG_H_SIZE + dsz); - if (skb_cow(buf, DIR_MSG_H_SIZE)) - return -ENOMEM; - - skb_push(buf, DIR_MSG_H_SIZE); - memcpy(buf->data, (unchar *)msg, DIR_MSG_H_SIZE); - msg_dbg(msg, "buf2port: "); - p_ptr->sent++; - if (dest->node == tipc_own_addr) - return port_recv_msg(buf); - res = tipc_send_buf_fast(buf, dest->node); - if (likely(res != -ELINKCONG)) - return res; - if (port_unreliable(p_ptr)) - return dsz; - return -ELINKCONG; -} - -/** - * tipc_send_buf2port - send message buffer to port identity - */ - -int tipc_send_buf2port(u32 ref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz) -{ - struct tipc_portid orig; - - orig.ref = ref; - orig.node = tipc_own_addr; - return tipc_forward_buf2port(ref, dest, buf, dsz, &orig, - TIPC_PORT_IMPORTANCE); -} - diff --git a/trunk/net/tipc/port.h b/trunk/net/tipc/port.h deleted file mode 100644 index e829a99d3b7f..000000000000 --- a/trunk/net/tipc/port.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * net/tipc/port.h: Include file for TIPC port code - * - * Copyright (c) 1994-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_PORT_H -#define _TIPC_PORT_H - -#include -#include "ref.h" -#include "net.h" -#include "msg.h" -#include "dbg.h" -#include "node_subscr.h" - -/** - * struct user_port - TIPC user port (used with native API) - * @user_ref: id of user who created user port - * @usr_handle: user-specified field - * @ref: object reference to associated TIPC port - * - * @uport_list: adjacent user ports in list of ports held by user - */ - -struct user_port { - u32 user_ref; - void *usr_handle; - u32 ref; - tipc_msg_err_event err_cb; - tipc_named_msg_err_event named_err_cb; - tipc_conn_shutdown_event conn_err_cb; - tipc_msg_event msg_cb; - tipc_named_msg_event named_msg_cb; - tipc_conn_msg_event conn_msg_cb; - tipc_continue_event continue_event_cb; - struct list_head uport_list; -}; - -/** - * struct port - TIPC port structure - * @publ: TIPC port info available to privileged users - * @port_list: adjacent ports in TIPC's global list of ports - * @dispatcher: ptr to routine which handles received messages - * @wakeup: ptr to routine to call when port is no longer congested - * @user_port: ptr to user port associated with port (if any) - * @wait_list: adjacent ports in list of ports waiting on link congestion - * @congested_link: ptr to congested link port is waiting on - * @waiting_pkts: - * @sent: - * @acked: - * @publications: list of publications for port - * @pub_count: total # of publications port has made during its lifetime - * @max_pkt: maximum packet size "hint" used when building messages sent by port - * @probing_state: - * @probing_interval: - * @last_in_seqno: - * @timer_ref: - * @subscription: "node down" subscription used to terminate failed connections - */ - -struct port { - struct tipc_port publ; - struct list_head port_list; - u32 (*dispatcher)(struct tipc_port *, struct sk_buff *); - void (*wakeup)(struct tipc_port *); - struct user_port *user_port; - struct list_head wait_list; - struct link *congested_link; - u32 waiting_pkts; - u32 sent; - u32 acked; - struct list_head publications; - u32 pub_count; - u32 max_pkt; - u32 probing_state; - u32 probing_interval; - u32 last_in_seqno; - struct timer_list timer; - struct node_subscr subscription; -}; - -extern spinlock_t port_list_lock; -struct port_list; - -int port_recv_sections(struct port *p_ptr, u32 num_sect, - struct iovec const *msg_sect); -int port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, - struct iovec const *msg_sect, u32 num_sect, - int err); -struct sk_buff *port_get_ports(void); -struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space); -void port_recv_proto_msg(struct sk_buff *buf); -void port_recv_mcast(struct sk_buff *buf, struct port_list *dp); -void port_reinit(void); - -/** - * port_lock - lock port instance referred to and return its pointer - */ - -static inline struct port *port_lock(u32 ref) -{ - return (struct port *)ref_lock(ref); -} - -/** - * port_unlock - unlock a port instance - * - * Can use pointer instead of ref_unlock() since port is already locked. - */ - -static inline void port_unlock(struct port *p_ptr) -{ - spin_unlock_bh(p_ptr->publ.lock); -} - -static inline struct port* port_deref(u32 ref) -{ - return (struct port *)ref_deref(ref); -} - -static inline u32 peer_port(struct port *p_ptr) -{ - return msg_destport(&p_ptr->publ.phdr); -} - -static inline u32 peer_node(struct port *p_ptr) -{ - return msg_destnode(&p_ptr->publ.phdr); -} - -static inline int port_congested(struct port *p_ptr) -{ - return((p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2)); -} - -/** - * port_recv_msg - receive message from lower layer and deliver to port user - */ - -static inline int port_recv_msg(struct sk_buff *buf) -{ - struct port *p_ptr; - struct tipc_msg *msg = buf_msg(buf); - u32 destport = msg_destport(msg); - u32 dsz = msg_data_sz(msg); - u32 err; - - /* forward unresolved named message */ - if (unlikely(!destport)) { - net_route_msg(buf); - return dsz; - } - - /* validate destination & pass to port, otherwise reject message */ - p_ptr = port_lock(destport); - if (likely(p_ptr)) { - if (likely(p_ptr->publ.connected)) { - if ((unlikely(msg_origport(msg) != peer_port(p_ptr))) || - (unlikely(msg_orignode(msg) != peer_node(p_ptr))) || - (unlikely(!msg_connected(msg)))) { - err = TIPC_ERR_NO_PORT; - port_unlock(p_ptr); - goto reject; - } - } - err = p_ptr->dispatcher(&p_ptr->publ, buf); - port_unlock(p_ptr); - if (likely(!err)) - return dsz; - } else { - err = TIPC_ERR_NO_PORT; - } -reject: - dbg("port->rejecting, err = %x..\n",err); - return tipc_reject_msg(buf, err); -} - -#endif diff --git a/trunk/net/tipc/ref.c b/trunk/net/tipc/ref.c deleted file mode 100644 index 944093fe246f..000000000000 --- a/trunk/net/tipc/ref.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * net/tipc/ref.c: TIPC object registry code - * - * Copyright (c) 1991-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "ref.h" -#include "port.h" -#include "subscr.h" -#include "name_distr.h" -#include "name_table.h" -#include "config.h" -#include "discover.h" -#include "bearer.h" -#include "node.h" -#include "bcast.h" - -/* - * Object reference table consists of 2**N entries. - * - * A used entry has object ptr != 0, reference == XXXX|own index - * (XXXX changes each time entry is acquired) - * A free entry has object ptr == 0, reference == YYYY|next free index - * (YYYY is one more than last used XXXX) - * - * Free list is initially chained from entry (2**N)-1 to entry 1. - * Entry 0 is not used to allow index 0 to indicate the end of the free list. - * - * Note: Any accidental reference of the form XXXX|0--0 won't match entry 0 - * because entry 0's reference field has the form XXXX|1--1. - */ - -struct ref_table ref_table = { 0 }; - -rwlock_t reftbl_lock = RW_LOCK_UNLOCKED; - -/** - * ref_table_init - create reference table for objects - */ - -int ref_table_init(u32 requested_size, u32 start) -{ - struct reference *table; - u32 sz = 1 << 4; - u32 index_mask; - int i; - - while (sz < requested_size) { - sz <<= 1; - } - table = (struct reference *)vmalloc(sz * sizeof(struct reference)); - if (table == NULL) - return -ENOMEM; - - write_lock_bh(&reftbl_lock); - index_mask = sz - 1; - for (i = sz - 1; i >= 0; i--) { - table[i].object = 0; - table[i].lock = SPIN_LOCK_UNLOCKED; - table[i].data.next_plus_upper = (start & ~index_mask) + i - 1; - } - ref_table.entries = table; - ref_table.index_mask = index_mask; - ref_table.first_free = sz - 1; - ref_table.last_free = 1; - write_unlock_bh(&reftbl_lock); - return TIPC_OK; -} - -/** - * ref_table_stop - destroy reference table for objects - */ - -void ref_table_stop(void) -{ - if (!ref_table.entries) - return; - - vfree(ref_table.entries); - ref_table.entries = 0; -} - -/** - * ref_acquire - create reference to an object - * - * Return a unique reference value which can be translated back to the pointer - * 'object' at a later time. Also, pass back a pointer to the lock protecting - * the object, but without locking it. - */ - -u32 ref_acquire(void *object, spinlock_t **lock) -{ - struct reference *entry; - u32 index; - u32 index_mask; - u32 next_plus_upper; - u32 reference = 0; - - assert(ref_table.entries && object); - - write_lock_bh(&reftbl_lock); - if (ref_table.first_free) { - index = ref_table.first_free; - entry = &(ref_table.entries[index]); - index_mask = ref_table.index_mask; - /* take lock in case a previous user of entry still holds it */ - spin_lock_bh(&entry->lock); - next_plus_upper = entry->data.next_plus_upper; - ref_table.first_free = next_plus_upper & index_mask; - reference = (next_plus_upper & ~index_mask) + index; - entry->data.reference = reference; - entry->object = object; - if (lock != 0) - *lock = &entry->lock; - spin_unlock_bh(&entry->lock); - } - write_unlock_bh(&reftbl_lock); - return reference; -} - -/** - * ref_discard - invalidate references to an object - * - * Disallow future references to an object and free up the entry for re-use. - * Note: The entry's spin_lock may still be busy after discard - */ - -void ref_discard(u32 ref) -{ - struct reference *entry; - u32 index; - u32 index_mask; - - assert(ref_table.entries); - assert(ref != 0); - - write_lock_bh(&reftbl_lock); - index_mask = ref_table.index_mask; - index = ref & index_mask; - entry = &(ref_table.entries[index]); - assert(entry->object != 0); - assert(entry->data.reference == ref); - - /* mark entry as unused */ - entry->object = 0; - if (ref_table.first_free == 0) - ref_table.first_free = index; - else - /* next_plus_upper is always XXXX|0--0 for last free entry */ - ref_table.entries[ref_table.last_free].data.next_plus_upper - |= index; - ref_table.last_free = index; - - /* increment upper bits of entry to invalidate subsequent references */ - entry->data.next_plus_upper = (ref & ~index_mask) + (index_mask + 1); - write_unlock_bh(&reftbl_lock); -} - diff --git a/trunk/net/tipc/ref.h b/trunk/net/tipc/ref.h deleted file mode 100644 index 429cde57228a..000000000000 --- a/trunk/net/tipc/ref.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * net/tipc/ref.h: Include file for TIPC object registry code - * - * Copyright (c) 1991-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_REF_H -#define _TIPC_REF_H - -/** - * struct reference - TIPC object reference entry - * @object: pointer to object associated with reference entry - * @lock: spinlock controlling access to object - * @data: reference value associated with object (or link to next unused entry) - */ - -struct reference { - void *object; - spinlock_t lock; - union { - u32 next_plus_upper; - u32 reference; - } data; -}; - -/** - * struct ref_table - table of TIPC object reference entries - * @entries: pointer to array of reference entries - * @index_mask: bitmask for array index portion of reference values - * @first_free: array index of first unused object reference entry - * @last_free: array index of last unused object reference entry - */ - -struct ref_table { - struct reference *entries; - u32 index_mask; - u32 first_free; - u32 last_free; -}; - -extern struct ref_table ref_table; - -int ref_table_init(u32 requested_size, u32 start); -void ref_table_stop(void); - -u32 ref_acquire(void *object, spinlock_t **lock); -void ref_discard(u32 ref); - - -/** - * ref_lock - lock referenced object and return pointer to it - */ - -static inline void *ref_lock(u32 ref) -{ - if (likely(ref_table.entries)) { - struct reference *r = - &ref_table.entries[ref & ref_table.index_mask]; - - spin_lock_bh(&r->lock); - if (likely(r->data.reference == ref)) - return r->object; - spin_unlock_bh(&r->lock); - } - return 0; -} - -/** - * ref_unlock - unlock referenced object - */ - -static inline void ref_unlock(u32 ref) -{ - if (likely(ref_table.entries)) { - struct reference *r = - &ref_table.entries[ref & ref_table.index_mask]; - - if (likely(r->data.reference == ref)) - spin_unlock_bh(&r->lock); - else - err("ref_unlock() invoked using obsolete reference\n"); - } -} - -/** - * ref_deref - return pointer referenced object (without locking it) - */ - -static inline void *ref_deref(u32 ref) -{ - if (likely(ref_table.entries)) { - struct reference *r = - &ref_table.entries[ref & ref_table.index_mask]; - - if (likely(r->data.reference == ref)) - return r->object; - } - return 0; -} - -#endif diff --git a/trunk/net/tipc/socket.c b/trunk/net/tipc/socket.c deleted file mode 100644 index d21f8c0cd25a..000000000000 --- a/trunk/net/tipc/socket.c +++ /dev/null @@ -1,1726 +0,0 @@ -/* - * net/tipc/socket.c: TIPC socket API - * - * Copyright (c) 2001-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "core.h" - -#define SS_LISTENING -1 /* socket is listening */ -#define SS_READY -2 /* socket is connectionless */ - -#define OVERLOAD_LIMIT_BASE 5000 - -struct tipc_sock { - struct sock sk; - struct tipc_port *p; - struct semaphore sem; -}; - -#define tipc_sk(sk) ((struct tipc_sock*)sk) - -static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf); -static void wakeupdispatch(struct tipc_port *tport); - -static struct proto_ops packet_ops; -static struct proto_ops stream_ops; -static struct proto_ops msg_ops; - -static struct proto tipc_proto; - -static int sockets_enabled = 0; - -static atomic_t tipc_queue_size = ATOMIC_INIT(0); - - -/* - * sock_lock(): Lock a port/socket pair. lock_sock() can - * not be used here, since the same lock must protect ports - * with non-socket interfaces. - * See net.c for description of locking policy. - */ -static inline void sock_lock(struct tipc_sock* tsock) -{ - spin_lock_bh(tsock->p->lock); -} - -/* - * sock_unlock(): Unlock a port/socket pair - */ -static inline void sock_unlock(struct tipc_sock* tsock) -{ - spin_unlock_bh(tsock->p->lock); -} - -/** - * pollmask - determine the current set of poll() events for a socket - * @sock: socket structure - * - * TIPC sets the returned events as follows: - * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty - * or if a connection-oriented socket is does not have an active connection - * (i.e. a read operation will not block). - * b) POLLOUT is set except when a socket's connection has been terminated - * (i.e. a write operation will not block). - * c) POLLHUP is set when a socket's connection has been terminated. - * - * IMPORTANT: The fact that a read or write operation will not block does NOT - * imply that the operation will succeed! - * - * Returns pollmask value - */ - -static inline u32 pollmask(struct socket *sock) -{ - u32 mask; - - if ((skb_queue_len(&sock->sk->sk_receive_queue) != 0) || - (sock->state == SS_UNCONNECTED) || - (sock->state == SS_DISCONNECTING)) - mask = (POLLRDNORM | POLLIN); - else - mask = 0; - - if (sock->state == SS_DISCONNECTING) - mask |= POLLHUP; - else - mask |= POLLOUT; - - return mask; -} - - -/** - * advance_queue - discard first buffer in queue - * @tsock: TIPC socket - */ - -static inline void advance_queue(struct tipc_sock *tsock) -{ - sock_lock(tsock); - buf_discard(skb_dequeue(&tsock->sk.sk_receive_queue)); - sock_unlock(tsock); - atomic_dec(&tipc_queue_size); -} - -/** - * tipc_create - create a TIPC socket - * @sock: pre-allocated socket structure - * @protocol: protocol indicator (must be 0) - * - * This routine creates and attaches a 'struct sock' to the 'struct socket', - * then create and attaches a TIPC port to the 'struct sock' part. - * - * Returns 0 on success, errno otherwise - */ -static int tipc_create(struct socket *sock, int protocol) -{ - struct tipc_sock *tsock; - struct tipc_port *port; - struct sock *sk; - u32 ref; - - if ((sock->type != SOCK_STREAM) && - (sock->type != SOCK_SEQPACKET) && - (sock->type != SOCK_DGRAM) && - (sock->type != SOCK_RDM)) - return -EPROTOTYPE; - - if (unlikely(protocol != 0)) - return -EPROTONOSUPPORT; - - ref = tipc_createport_raw(0, &dispatch, &wakeupdispatch, TIPC_LOW_IMPORTANCE); - if (unlikely(!ref)) - return -ENOMEM; - - sock->state = SS_UNCONNECTED; - - switch (sock->type) { - case SOCK_STREAM: - sock->ops = &stream_ops; - break; - case SOCK_SEQPACKET: - sock->ops = &packet_ops; - break; - case SOCK_DGRAM: - tipc_set_portunreliable(ref, 1); - /* fall through */ - case SOCK_RDM: - tipc_set_portunreturnable(ref, 1); - sock->ops = &msg_ops; - sock->state = SS_READY; - break; - } - - sk = sk_alloc(AF_TIPC, GFP_KERNEL, &tipc_proto, 1); - if (!sk) { - tipc_deleteport(ref); - return -ENOMEM; - } - - sock_init_data(sock, sk); - init_waitqueue_head(sk->sk_sleep); - sk->sk_rcvtimeo = 8 * HZ; /* default connect timeout = 8s */ - - tsock = tipc_sk(sk); - port = tipc_get_port(ref); - - tsock->p = port; - port->usr_handle = tsock; - - init_MUTEX(&tsock->sem); - - dbg("sock_create: %x\n",tsock); - - atomic_inc(&tipc_user_count); - - return 0; -} - -/** - * release - destroy a TIPC socket - * @sock: socket to destroy - * - * This routine cleans up any messages that are still queued on the socket. - * For DGRAM and RDM socket types, all queued messages are rejected. - * For SEQPACKET and STREAM socket types, the first message is rejected - * and any others are discarded. (If the first message on a STREAM socket - * is partially-read, it is discarded and the next one is rejected instead.) - * - * NOTE: Rejected messages are not necessarily returned to the sender! They - * are returned or discarded according to the "destination droppable" setting - * specified for the message by the sender. - * - * Returns 0 on success, errno otherwise - */ - -static int release(struct socket *sock) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct sock *sk = sock->sk; - int res = TIPC_OK; - struct sk_buff *buf; - - dbg("sock_delete: %x\n",tsock); - if (!tsock) - return 0; - down_interruptible(&tsock->sem); - if (!sock->sk) { - up(&tsock->sem); - return 0; - } - - /* Reject unreceived messages, unless no longer connected */ - - while (sock->state != SS_DISCONNECTING) { - sock_lock(tsock); - buf = skb_dequeue(&sk->sk_receive_queue); - if (!buf) - tsock->p->usr_handle = 0; - sock_unlock(tsock); - if (!buf) - break; - if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) - buf_discard(buf); - else - tipc_reject_msg(buf, TIPC_ERR_NO_PORT); - atomic_dec(&tipc_queue_size); - } - - /* Delete TIPC port */ - - res = tipc_deleteport(tsock->p->ref); - sock->sk = NULL; - - /* Discard any remaining messages */ - - while ((buf = skb_dequeue(&sk->sk_receive_queue))) { - buf_discard(buf); - atomic_dec(&tipc_queue_size); - } - - up(&tsock->sem); - - sock_put(sk); - - atomic_dec(&tipc_user_count); - return res; -} - -/** - * bind - associate or disassocate TIPC name(s) with a socket - * @sock: socket structure - * @uaddr: socket address describing name(s) and desired operation - * @uaddr_len: size of socket address data structure - * - * Name and name sequence binding is indicated using a positive scope value; - * a negative scope value unbinds the specified name. Specifying no name - * (i.e. a socket address length of 0) unbinds all names from the socket. - * - * Returns 0 on success, errno otherwise - */ - -static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; - int res; - - if (down_interruptible(&tsock->sem)) - return -ERESTARTSYS; - - if (unlikely(!uaddr_len)) { - res = tipc_withdraw(tsock->p->ref, 0, 0); - goto exit; - } - - if (uaddr_len < sizeof(struct sockaddr_tipc)) { - res = -EINVAL; - goto exit; - } - - if (addr->family != AF_TIPC) { - res = -EAFNOSUPPORT; - goto exit; - } - if (addr->addrtype == TIPC_ADDR_NAME) - addr->addr.nameseq.upper = addr->addr.nameseq.lower; - else if (addr->addrtype != TIPC_ADDR_NAMESEQ) { - res = -EAFNOSUPPORT; - goto exit; - } - - if (addr->scope > 0) - res = tipc_publish(tsock->p->ref, addr->scope, - &addr->addr.nameseq); - else - res = tipc_withdraw(tsock->p->ref, -addr->scope, - &addr->addr.nameseq); -exit: - up(&tsock->sem); - return res; -} - -/** - * get_name - get port ID of socket or peer socket - * @sock: socket structure - * @uaddr: area for returned socket address - * @uaddr_len: area for returned length of socket address - * @peer: 0 to obtain socket name, 1 to obtain peer socket name - * - * Returns 0 on success, errno otherwise - */ - -static int get_name(struct socket *sock, struct sockaddr *uaddr, - int *uaddr_len, int peer) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr; - u32 res; - - if (down_interruptible(&tsock->sem)) - return -ERESTARTSYS; - - *uaddr_len = sizeof(*addr); - addr->addrtype = TIPC_ADDR_ID; - addr->family = AF_TIPC; - addr->scope = 0; - if (peer) - res = tipc_peer(tsock->p->ref, &addr->addr.id); - else - res = tipc_ownidentity(tsock->p->ref, &addr->addr.id); - addr->addr.name.domain = 0; - - up(&tsock->sem); - return res; -} - -/** - * poll - read and possibly block on pollmask - * @file: file structure associated with the socket - * @sock: socket for which to calculate the poll bits - * @wait: ??? - * - * Returns the pollmask - */ - -static unsigned int poll(struct file *file, struct socket *sock, - poll_table *wait) -{ - poll_wait(file, sock->sk->sk_sleep, wait); - /* NEED LOCK HERE? */ - return pollmask(sock); -} - -/** - * dest_name_check - verify user is permitted to send to specified port name - * @dest: destination address - * @m: descriptor for message to be sent - * - * Prevents restricted configuration commands from being issued by - * unauthorized users. - * - * Returns 0 if permission is granted, otherwise errno - */ - -static inline int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m) -{ - struct tipc_cfg_msg_hdr hdr; - - if (likely(dest->addr.name.name.type >= TIPC_RESERVED_TYPES)) - return 0; - if (likely(dest->addr.name.name.type == TIPC_TOP_SRV)) - return 0; - - if (likely(dest->addr.name.name.type != TIPC_CFG_SRV)) - return -EACCES; - - if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr))) - return -EFAULT; - if ((ntohs(hdr.tcm_type) & 0xC000) & (!capable(CAP_NET_ADMIN))) - return -EACCES; - - return 0; -} - -/** - * send_msg - send message in connectionless manner - * @iocb: (unused) - * @sock: socket structure - * @m: message to send - * @total_len: (unused) - * - * Message must have an destination specified explicitly. - * Used for SOCK_RDM and SOCK_DGRAM messages, - * and for 'SYN' messages on SOCK_SEQPACKET and SOCK_STREAM connections. - * (Note: 'SYN+' is prohibited on SOCK_STREAM.) - * - * Returns the number of bytes sent on success, or errno otherwise - */ - -static int send_msg(struct kiocb *iocb, struct socket *sock, - struct msghdr *m, size_t total_len) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; - struct sk_buff *buf; - int needs_conn; - int res = -EINVAL; - - if (unlikely(!dest)) - return -EDESTADDRREQ; - if (unlikely(dest->family != AF_TIPC)) - return -EINVAL; - - needs_conn = (sock->state != SS_READY); - if (unlikely(needs_conn)) { - if (sock->state == SS_LISTENING) - return -EPIPE; - if (sock->state != SS_UNCONNECTED) - return -EISCONN; - if ((tsock->p->published) || - ((sock->type == SOCK_STREAM) && (total_len != 0))) - return -EOPNOTSUPP; - } - - if (down_interruptible(&tsock->sem)) - return -ERESTARTSYS; - - if (needs_conn) { - - /* Abort any pending connection attempts (very unlikely) */ - - while ((buf = skb_dequeue(&sock->sk->sk_receive_queue))) { - tipc_reject_msg(buf, TIPC_ERR_NO_PORT); - atomic_dec(&tipc_queue_size); - } - - sock->state = SS_CONNECTING; - } - - do { - if (dest->addrtype == TIPC_ADDR_NAME) { - if ((res = dest_name_check(dest, m))) - goto exit; - res = tipc_send2name(tsock->p->ref, - &dest->addr.name.name, - dest->addr.name.domain, - m->msg_iovlen, - m->msg_iov); - } - else if (dest->addrtype == TIPC_ADDR_ID) { - res = tipc_send2port(tsock->p->ref, - &dest->addr.id, - m->msg_iovlen, - m->msg_iov); - } - else if (dest->addrtype == TIPC_ADDR_MCAST) { - if (needs_conn) { - res = -EOPNOTSUPP; - goto exit; - } - if ((res = dest_name_check(dest, m))) - goto exit; - res = tipc_multicast(tsock->p->ref, - &dest->addr.nameseq, - 0, - m->msg_iovlen, - m->msg_iov); - } - if (likely(res != -ELINKCONG)) { -exit: - up(&tsock->sem); - return res; - } - if (m->msg_flags & MSG_DONTWAIT) { - res = -EWOULDBLOCK; - goto exit; - } - if (wait_event_interruptible(*sock->sk->sk_sleep, - !tsock->p->congested)) { - res = -ERESTARTSYS; - goto exit; - } - } while (1); -} - -/** - * send_packet - send a connection-oriented message - * @iocb: (unused) - * @sock: socket structure - * @m: message to send - * @total_len: (unused) - * - * Used for SOCK_SEQPACKET messages and SOCK_STREAM data. - * - * Returns the number of bytes sent on success, or errno otherwise - */ - -static int send_packet(struct kiocb *iocb, struct socket *sock, - struct msghdr *m, size_t total_len) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; - int res; - - /* Handle implied connection establishment */ - - if (unlikely(dest)) - return send_msg(iocb, sock, m, total_len); - - if (down_interruptible(&tsock->sem)) { - return -ERESTARTSYS; - } - - if (unlikely(sock->state != SS_CONNECTED)) { - if (sock->state == SS_DISCONNECTING) - res = -EPIPE; - else - res = -ENOTCONN; - goto exit; - } - - do { - res = tipc_send(tsock->p->ref, m->msg_iovlen, m->msg_iov); - if (likely(res != -ELINKCONG)) { -exit: - up(&tsock->sem); - return res; - } - if (m->msg_flags & MSG_DONTWAIT) { - res = -EWOULDBLOCK; - goto exit; - } - if (wait_event_interruptible(*sock->sk->sk_sleep, - !tsock->p->congested)) { - res = -ERESTARTSYS; - goto exit; - } - } while (1); -} - -/** - * send_stream - send stream-oriented data - * @iocb: (unused) - * @sock: socket structure - * @m: data to send - * @total_len: total length of data to be sent - * - * Used for SOCK_STREAM data. - * - * Returns the number of bytes sent on success, or errno otherwise - */ - - -static int send_stream(struct kiocb *iocb, struct socket *sock, - struct msghdr *m, size_t total_len) -{ - struct msghdr my_msg; - struct iovec my_iov; - struct iovec *curr_iov; - int curr_iovlen; - char __user *curr_start; - int curr_left; - int bytes_to_send; - int res; - - if (likely(total_len <= TIPC_MAX_USER_MSG_SIZE)) - return send_packet(iocb, sock, m, total_len); - - /* Can only send large data streams if already connected */ - - if (unlikely(sock->state != SS_CONNECTED)) { - if (sock->state == SS_DISCONNECTING) - return -EPIPE; - else - return -ENOTCONN; - } - - /* - * Send each iovec entry using one or more messages - * - * Note: This algorithm is good for the most likely case - * (i.e. one large iovec entry), but could be improved to pass sets - * of small iovec entries into send_packet(). - */ - - my_msg = *m; - curr_iov = my_msg.msg_iov; - curr_iovlen = my_msg.msg_iovlen; - my_msg.msg_iov = &my_iov; - my_msg.msg_iovlen = 1; - - while (curr_iovlen--) { - curr_start = curr_iov->iov_base; - curr_left = curr_iov->iov_len; - - while (curr_left) { - bytes_to_send = (curr_left < TIPC_MAX_USER_MSG_SIZE) - ? curr_left : TIPC_MAX_USER_MSG_SIZE; - my_iov.iov_base = curr_start; - my_iov.iov_len = bytes_to_send; - if ((res = send_packet(iocb, sock, &my_msg, 0)) < 0) - return res; - curr_left -= bytes_to_send; - curr_start += bytes_to_send; - } - - curr_iov++; - } - - return total_len; -} - -/** - * auto_connect - complete connection setup to a remote port - * @sock: socket structure - * @tsock: TIPC-specific socket structure - * @msg: peer's response message - * - * Returns 0 on success, errno otherwise - */ - -static int auto_connect(struct socket *sock, struct tipc_sock *tsock, - struct tipc_msg *msg) -{ - struct tipc_portid peer; - - if (msg_errcode(msg)) { - sock->state = SS_DISCONNECTING; - return -ECONNREFUSED; - } - - peer.ref = msg_origport(msg); - peer.node = msg_orignode(msg); - tipc_connect2port(tsock->p->ref, &peer); - tipc_set_portimportance(tsock->p->ref, msg_importance(msg)); - sock->state = SS_CONNECTED; - return 0; -} - -/** - * set_orig_addr - capture sender's address for received message - * @m: descriptor for message info - * @msg: received message header - * - * Note: Address is not captured if not requested by receiver. - */ - -static inline void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) -{ - struct sockaddr_tipc *addr = (struct sockaddr_tipc *)m->msg_name; - - if (addr) { - addr->family = AF_TIPC; - addr->addrtype = TIPC_ADDR_ID; - addr->addr.id.ref = msg_origport(msg); - addr->addr.id.node = msg_orignode(msg); - addr->addr.name.domain = 0; /* could leave uninitialized */ - addr->scope = 0; /* could leave uninitialized */ - m->msg_namelen = sizeof(struct sockaddr_tipc); - } -} - -/** - * anc_data_recv - optionally capture ancillary data for received message - * @m: descriptor for message info - * @msg: received message header - * @tport: TIPC port associated with message - * - * Note: Ancillary data is not captured if not requested by receiver. - * - * Returns 0 if successful, otherwise errno - */ - -static inline int anc_data_recv(struct msghdr *m, struct tipc_msg *msg, - struct tipc_port *tport) -{ - u32 anc_data[3]; - u32 err; - u32 dest_type; - int res; - - if (likely(m->msg_controllen == 0)) - return 0; - - /* Optionally capture errored message object(s) */ - - err = msg ? msg_errcode(msg) : 0; - if (unlikely(err)) { - anc_data[0] = err; - anc_data[1] = msg_data_sz(msg); - if ((res = put_cmsg(m, SOL_SOCKET, TIPC_ERRINFO, 8, anc_data))) - return res; - if (anc_data[1] && - (res = put_cmsg(m, SOL_SOCKET, TIPC_RETDATA, anc_data[1], - msg_data(msg)))) - return res; - } - - /* Optionally capture message destination object */ - - dest_type = msg ? msg_type(msg) : TIPC_DIRECT_MSG; - switch (dest_type) { - case TIPC_NAMED_MSG: - anc_data[0] = msg_nametype(msg); - anc_data[1] = msg_namelower(msg); - anc_data[2] = msg_namelower(msg); - break; - case TIPC_MCAST_MSG: - anc_data[0] = msg_nametype(msg); - anc_data[1] = msg_namelower(msg); - anc_data[2] = msg_nameupper(msg); - break; - case TIPC_CONN_MSG: - anc_data[0] = tport->conn_type; - anc_data[1] = tport->conn_instance; - anc_data[2] = tport->conn_instance; - break; - default: - anc_data[0] = 0; - } - if (anc_data[0] && - (res = put_cmsg(m, SOL_SOCKET, TIPC_DESTNAME, 12, anc_data))) - return res; - - return 0; -} - -/** - * recv_msg - receive packet-oriented message - * @iocb: (unused) - * @m: descriptor for message info - * @buf_len: total size of user buffer area - * @flags: receive flags - * - * Used for SOCK_DGRAM, SOCK_RDM, and SOCK_SEQPACKET messages. - * If the complete message doesn't fit in user area, truncate it. - * - * Returns size of returned message data, errno otherwise - */ - -static int recv_msg(struct kiocb *iocb, struct socket *sock, - struct msghdr *m, size_t buf_len, int flags) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct sk_buff *buf; - struct tipc_msg *msg; - unsigned int q_len; - unsigned int sz; - u32 err; - int res; - - /* Currently doesn't support receiving into multiple iovec entries */ - - if (m->msg_iovlen != 1) - return -EOPNOTSUPP; - - /* Catch invalid receive attempts */ - - if (unlikely(!buf_len)) - return -EINVAL; - - if (sock->type == SOCK_SEQPACKET) { - if (unlikely(sock->state == SS_UNCONNECTED)) - return -ENOTCONN; - if (unlikely((sock->state == SS_DISCONNECTING) && - (skb_queue_len(&sock->sk->sk_receive_queue) == 0))) - return -ENOTCONN; - } - - /* Look for a message in receive queue; wait if necessary */ - - if (unlikely(down_interruptible(&tsock->sem))) - return -ERESTARTSYS; - -restart: - if (unlikely((skb_queue_len(&sock->sk->sk_receive_queue) == 0) && - (flags & MSG_DONTWAIT))) { - res = -EWOULDBLOCK; - goto exit; - } - - if ((res = wait_event_interruptible( - *sock->sk->sk_sleep, - ((q_len = skb_queue_len(&sock->sk->sk_receive_queue)) || - (sock->state == SS_DISCONNECTING))) )) { - goto exit; - } - - /* Catch attempt to receive on an already terminated connection */ - /* [THIS CHECK MAY OVERLAP WITH AN EARLIER CHECK] */ - - if (!q_len) { - res = -ENOTCONN; - goto exit; - } - - /* Get access to first message in receive queue */ - - buf = skb_peek(&sock->sk->sk_receive_queue); - msg = buf_msg(buf); - sz = msg_data_sz(msg); - err = msg_errcode(msg); - - /* Complete connection setup for an implied connect */ - - if (unlikely(sock->state == SS_CONNECTING)) { - if ((res = auto_connect(sock, tsock, msg))) - goto exit; - } - - /* Discard an empty non-errored message & try again */ - - if ((!sz) && (!err)) { - advance_queue(tsock); - goto restart; - } - - /* Capture sender's address (optional) */ - - set_orig_addr(m, msg); - - /* Capture ancillary data (optional) */ - - if ((res = anc_data_recv(m, msg, tsock->p))) - goto exit; - - /* Capture message data (if valid) & compute return value (always) */ - - if (!err) { - if (unlikely(buf_len < sz)) { - sz = buf_len; - m->msg_flags |= MSG_TRUNC; - } - if (unlikely(copy_to_user(m->msg_iov->iov_base, msg_data(msg), - sz))) { - res = -EFAULT; - goto exit; - } - res = sz; - } else { - if ((sock->state == SS_READY) || - ((err == TIPC_CONN_SHUTDOWN) || m->msg_control)) - res = 0; - else - res = -ECONNRESET; - } - - /* Consume received message (optional) */ - - if (likely(!(flags & MSG_PEEK))) { - if (unlikely(++tsock->p->conn_unacked >= TIPC_FLOW_CONTROL_WIN)) - tipc_acknowledge(tsock->p->ref, tsock->p->conn_unacked); - advance_queue(tsock); - } -exit: - up(&tsock->sem); - return res; -} - -/** - * recv_stream - receive stream-oriented data - * @iocb: (unused) - * @m: descriptor for message info - * @buf_len: total size of user buffer area - * @flags: receive flags - * - * Used for SOCK_STREAM messages only. If not enough data is available - * will optionally wait for more; never truncates data. - * - * Returns size of returned message data, errno otherwise - */ - -static int recv_stream(struct kiocb *iocb, struct socket *sock, - struct msghdr *m, size_t buf_len, int flags) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct sk_buff *buf; - struct tipc_msg *msg; - unsigned int q_len; - unsigned int sz; - int sz_to_copy; - int sz_copied = 0; - int needed; - char *crs = m->msg_iov->iov_base; - unsigned char *buf_crs; - u32 err; - int res; - - /* Currently doesn't support receiving into multiple iovec entries */ - - if (m->msg_iovlen != 1) - return -EOPNOTSUPP; - - /* Catch invalid receive attempts */ - - if (unlikely(!buf_len)) - return -EINVAL; - - if (unlikely(sock->state == SS_DISCONNECTING)) { - if (skb_queue_len(&sock->sk->sk_receive_queue) == 0) - return -ENOTCONN; - } else if (unlikely(sock->state != SS_CONNECTED)) - return -ENOTCONN; - - /* Look for a message in receive queue; wait if necessary */ - - if (unlikely(down_interruptible(&tsock->sem))) - return -ERESTARTSYS; - -restart: - if (unlikely((skb_queue_len(&sock->sk->sk_receive_queue) == 0) && - (flags & MSG_DONTWAIT))) { - res = (sz_copied == 0) ? -EWOULDBLOCK : 0; - goto exit; - } - - if ((res = wait_event_interruptible( - *sock->sk->sk_sleep, - ((q_len = skb_queue_len(&sock->sk->sk_receive_queue)) || - (sock->state == SS_DISCONNECTING))) )) { - goto exit; - } - - /* Catch attempt to receive on an already terminated connection */ - /* [THIS CHECK MAY OVERLAP WITH AN EARLIER CHECK] */ - - if (!q_len) { - res = -ENOTCONN; - goto exit; - } - - /* Get access to first message in receive queue */ - - buf = skb_peek(&sock->sk->sk_receive_queue); - msg = buf_msg(buf); - sz = msg_data_sz(msg); - err = msg_errcode(msg); - - /* Discard an empty non-errored message & try again */ - - if ((!sz) && (!err)) { - advance_queue(tsock); - goto restart; - } - - /* Optionally capture sender's address & ancillary data of first msg */ - - if (sz_copied == 0) { - set_orig_addr(m, msg); - if ((res = anc_data_recv(m, msg, tsock->p))) - goto exit; - } - - /* Capture message data (if valid) & compute return value (always) */ - - if (!err) { - buf_crs = (unsigned char *)(TIPC_SKB_CB(buf)->handle); - sz = buf->tail - buf_crs; - - needed = (buf_len - sz_copied); - sz_to_copy = (sz <= needed) ? sz : needed; - if (unlikely(copy_to_user(crs, buf_crs, sz_to_copy))) { - res = -EFAULT; - goto exit; - } - sz_copied += sz_to_copy; - - if (sz_to_copy < sz) { - if (!(flags & MSG_PEEK)) - TIPC_SKB_CB(buf)->handle = buf_crs + sz_to_copy; - goto exit; - } - - crs += sz_to_copy; - } else { - if (sz_copied != 0) - goto exit; /* can't add error msg to valid data */ - - if ((err == TIPC_CONN_SHUTDOWN) || m->msg_control) - res = 0; - else - res = -ECONNRESET; - } - - /* Consume received message (optional) */ - - if (likely(!(flags & MSG_PEEK))) { - if (unlikely(++tsock->p->conn_unacked >= TIPC_FLOW_CONTROL_WIN)) - tipc_acknowledge(tsock->p->ref, tsock->p->conn_unacked); - advance_queue(tsock); - } - - /* Loop around if more data is required */ - - if ((sz_copied < buf_len) /* didn't get all requested data */ - && (flags & MSG_WAITALL) /* ... and need to wait for more */ - && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */ - && (!err) /* ... and haven't reached a FIN */ - ) - goto restart; - -exit: - up(&tsock->sem); - return res ? res : sz_copied; -} - -/** - * queue_overloaded - test if queue overload condition exists - * @queue_size: current size of queue - * @base: nominal maximum size of queue - * @msg: message to be added to queue - * - * Returns 1 if queue is currently overloaded, 0 otherwise - */ - -static int queue_overloaded(u32 queue_size, u32 base, struct tipc_msg *msg) -{ - u32 threshold; - u32 imp = msg_importance(msg); - - if (imp == TIPC_LOW_IMPORTANCE) - threshold = base; - else if (imp == TIPC_MEDIUM_IMPORTANCE) - threshold = base * 2; - else if (imp == TIPC_HIGH_IMPORTANCE) - threshold = base * 100; - else - return 0; - - if (msg_connected(msg)) - threshold *= 4; - - return (queue_size > threshold); -} - -/** - * async_disconnect - wrapper function used to disconnect port - * @portref: TIPC port reference (passed as pointer-sized value) - */ - -static void async_disconnect(unsigned long portref) -{ - tipc_disconnect((u32)portref); -} - -/** - * dispatch - handle arriving message - * @tport: TIPC port that received message - * @buf: message - * - * Called with port locked. Must not take socket lock to avoid deadlock risk. - * - * Returns TIPC error status code (TIPC_OK if message is not to be rejected) - */ - -static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf) -{ - struct tipc_msg *msg = buf_msg(buf); - struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle; - struct socket *sock; - u32 recv_q_len; - - /* Reject message if socket is closing */ - - if (!tsock) - return TIPC_ERR_NO_PORT; - - /* Reject message if it is wrong sort of message for socket */ - - /* - * WOULD IT BE BETTER TO JUST DISCARD THESE MESSAGES INSTEAD? - * "NO PORT" ISN'T REALLY THE RIGHT ERROR CODE, AND THERE MAY - * BE SECURITY IMPLICATIONS INHERENT IN REJECTING INVALID TRAFFIC - */ - sock = tsock->sk.sk_socket; - if (sock->state == SS_READY) { - if (msg_connected(msg)) { - msg_dbg(msg, "dispatch filter 1\n"); - return TIPC_ERR_NO_PORT; - } - } else { - if (msg_mcast(msg)) { - msg_dbg(msg, "dispatch filter 2\n"); - return TIPC_ERR_NO_PORT; - } - if (sock->state == SS_CONNECTED) { - if (!msg_connected(msg)) { - msg_dbg(msg, "dispatch filter 3\n"); - return TIPC_ERR_NO_PORT; - } - } - else if (sock->state == SS_CONNECTING) { - if (!msg_connected(msg) && (msg_errcode(msg) == 0)) { - msg_dbg(msg, "dispatch filter 4\n"); - return TIPC_ERR_NO_PORT; - } - } - else if (sock->state == SS_LISTENING) { - if (msg_connected(msg) || msg_errcode(msg)) { - msg_dbg(msg, "dispatch filter 5\n"); - return TIPC_ERR_NO_PORT; - } - } - else if (sock->state == SS_DISCONNECTING) { - msg_dbg(msg, "dispatch filter 6\n"); - return TIPC_ERR_NO_PORT; - } - else /* (sock->state == SS_UNCONNECTED) */ { - if (msg_connected(msg) || msg_errcode(msg)) { - msg_dbg(msg, "dispatch filter 7\n"); - return TIPC_ERR_NO_PORT; - } - } - } - - /* Reject message if there isn't room to queue it */ - - if (unlikely((u32)atomic_read(&tipc_queue_size) > - OVERLOAD_LIMIT_BASE)) { - if (queue_overloaded(atomic_read(&tipc_queue_size), - OVERLOAD_LIMIT_BASE, msg)) - return TIPC_ERR_OVERLOAD; - } - recv_q_len = skb_queue_len(&tsock->sk.sk_receive_queue); - if (unlikely(recv_q_len > (OVERLOAD_LIMIT_BASE / 2))) { - if (queue_overloaded(recv_q_len, - OVERLOAD_LIMIT_BASE / 2, msg)) - return TIPC_ERR_OVERLOAD; - } - - /* Initiate connection termination for an incoming 'FIN' */ - - if (unlikely(msg_errcode(msg) && (sock->state == SS_CONNECTED))) { - sock->state = SS_DISCONNECTING; - /* Note: Use signal since port lock is already taken! */ - k_signal((Handler)async_disconnect, tport->ref); - } - - /* Enqueue message (finally!) */ - - msg_dbg(msg,"handle = msg_data(msg); - atomic_inc(&tipc_queue_size); - skb_queue_tail(&sock->sk->sk_receive_queue, buf); - - wake_up_interruptible(sock->sk->sk_sleep); - return TIPC_OK; -} - -/** - * wakeupdispatch - wake up port after congestion - * @tport: port to wakeup - * - * Called with port lock on. - */ - -static void wakeupdispatch(struct tipc_port *tport) -{ - struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle; - - wake_up_interruptible(tsock->sk.sk_sleep); -} - -/** - * connect - establish a connection to another TIPC port - * @sock: socket structure - * @dest: socket address for destination port - * @destlen: size of socket address data structure - * @flags: (unused) - * - * Returns 0 on success, errno otherwise - */ - -static int connect(struct socket *sock, struct sockaddr *dest, int destlen, - int flags) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest; - struct msghdr m = {0,}; - struct sk_buff *buf; - struct tipc_msg *msg; - int res; - - /* For now, TIPC does not allow use of connect() with DGRAM or RDM types */ - - if (sock->state == SS_READY) - return -EOPNOTSUPP; - - /* MOVE THE REST OF THIS ERROR CHECKING TO send_msg()? */ - if (sock->state == SS_LISTENING) - return -EOPNOTSUPP; - if (sock->state == SS_CONNECTING) - return -EALREADY; - if (sock->state != SS_UNCONNECTED) - return -EISCONN; - - if ((dst->family != AF_TIPC) || - ((dst->addrtype != TIPC_ADDR_NAME) && (dst->addrtype != TIPC_ADDR_ID))) - return -EINVAL; - - /* Send a 'SYN-' to destination */ - - m.msg_name = dest; - if ((res = send_msg(0, sock, &m, 0)) < 0) { - sock->state = SS_DISCONNECTING; - return res; - } - - if (down_interruptible(&tsock->sem)) - return -ERESTARTSYS; - - /* Wait for destination's 'ACK' response */ - - res = wait_event_interruptible_timeout(*sock->sk->sk_sleep, - skb_queue_len(&sock->sk->sk_receive_queue), - sock->sk->sk_rcvtimeo); - buf = skb_peek(&sock->sk->sk_receive_queue); - if (res > 0) { - msg = buf_msg(buf); - res = auto_connect(sock, tsock, msg); - if (!res) { - if (dst->addrtype == TIPC_ADDR_NAME) { - tsock->p->conn_type = dst->addr.name.name.type; - tsock->p->conn_instance = dst->addr.name.name.instance; - } - if (!msg_data_sz(msg)) - advance_queue(tsock); - } - } else { - if (res == 0) { - res = -ETIMEDOUT; - } else - { /* leave "res" unchanged */ } - sock->state = SS_DISCONNECTING; - } - - up(&tsock->sem); - return res; -} - -/** - * listen - allow socket to listen for incoming connections - * @sock: socket structure - * @len: (unused) - * - * Returns 0 on success, errno otherwise - */ - -static int listen(struct socket *sock, int len) -{ - /* REQUIRES SOCKET LOCKING OF SOME SORT? */ - - if (sock->state == SS_READY) - return -EOPNOTSUPP; - if (sock->state != SS_UNCONNECTED) - return -EINVAL; - sock->state = SS_LISTENING; - return 0; -} - -/** - * accept - wait for connection request - * @sock: listening socket - * @newsock: new socket that is to be connected - * @flags: file-related flags associated with socket - * - * Returns 0 on success, errno otherwise - */ - -static int accept(struct socket *sock, struct socket *newsock, int flags) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - struct sk_buff *buf; - int res = -EFAULT; - - if (sock->state == SS_READY) - return -EOPNOTSUPP; - if (sock->state != SS_LISTENING) - return -EINVAL; - - if (unlikely((skb_queue_len(&sock->sk->sk_receive_queue) == 0) && - (flags & O_NONBLOCK))) - return -EWOULDBLOCK; - - if (down_interruptible(&tsock->sem)) - return -ERESTARTSYS; - - if (wait_event_interruptible(*sock->sk->sk_sleep, - skb_queue_len(&sock->sk->sk_receive_queue))) { - res = -ERESTARTSYS; - goto exit; - } - buf = skb_peek(&sock->sk->sk_receive_queue); - - res = tipc_create(newsock, 0); - if (!res) { - struct tipc_sock *new_tsock = tipc_sk(newsock->sk); - struct tipc_portid id; - struct tipc_msg *msg = buf_msg(buf); - u32 new_ref = new_tsock->p->ref; - - id.ref = msg_origport(msg); - id.node = msg_orignode(msg); - tipc_connect2port(new_ref, &id); - newsock->state = SS_CONNECTED; - - tipc_set_portimportance(new_ref, msg_importance(msg)); - if (msg_named(msg)) { - new_tsock->p->conn_type = msg_nametype(msg); - new_tsock->p->conn_instance = msg_nameinst(msg); - } - - /* - * Respond to 'SYN-' by discarding it & returning 'ACK'-. - * Respond to 'SYN+' by queuing it on new socket. - */ - - msg_dbg(msg,"sk->sk_receive_queue); - sock_unlock(tsock); - skb_queue_head(&newsock->sk->sk_receive_queue, buf); - } - } -exit: - up(&tsock->sem); - return res; -} - -/** - * shutdown - shutdown socket connection - * @sock: socket structure - * @how: direction to close (always treated as read + write) - * - * Terminates connection (if necessary), then purges socket's receive queue. - * - * Returns 0 on success, errno otherwise - */ - -static int shutdown(struct socket *sock, int how) -{ - struct tipc_sock* tsock = tipc_sk(sock->sk); - struct sk_buff *buf; - int res; - - /* Could return -EINVAL for an invalid "how", but why bother? */ - - if (down_interruptible(&tsock->sem)) - return -ERESTARTSYS; - - sock_lock(tsock); - - switch (sock->state) { - case SS_CONNECTED: - - /* Send 'FIN+' or 'FIN-' message to peer */ - - sock_unlock(tsock); -restart: - if ((buf = skb_dequeue(&sock->sk->sk_receive_queue))) { - atomic_dec(&tipc_queue_size); - if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) { - buf_discard(buf); - goto restart; - } - tipc_reject_msg(buf, TIPC_CONN_SHUTDOWN); - } - else { - tipc_shutdown(tsock->p->ref); - } - sock_lock(tsock); - - /* fall through */ - - case SS_DISCONNECTING: - - /* Discard any unreceived messages */ - - while ((buf = skb_dequeue(&sock->sk->sk_receive_queue))) { - atomic_dec(&tipc_queue_size); - buf_discard(buf); - } - tsock->p->conn_unacked = 0; - - /* fall through */ - - case SS_CONNECTING: - sock->state = SS_DISCONNECTING; - res = 0; - break; - - default: - res = -ENOTCONN; - } - - sock_unlock(tsock); - - up(&tsock->sem); - return res; -} - -/** - * setsockopt - set socket option - * @sock: socket structure - * @lvl: option level - * @opt: option identifier - * @ov: pointer to new option value - * @ol: length of option value - * - * For stream sockets only, accepts and ignores all IPPROTO_TCP options - * (to ease compatibility). - * - * Returns 0 on success, errno otherwise - */ - -static int setsockopt(struct socket *sock, int lvl, int opt, char *ov, int ol) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - u32 value; - int res; - - if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM)) - return 0; - if (lvl != SOL_TIPC) - return -ENOPROTOOPT; - if (ol < sizeof(value)) - return -EINVAL; - if ((res = get_user(value, (u32 *)ov))) - return res; - - if (down_interruptible(&tsock->sem)) - return -ERESTARTSYS; - - switch (opt) { - case TIPC_IMPORTANCE: - res = tipc_set_portimportance(tsock->p->ref, value); - break; - case TIPC_SRC_DROPPABLE: - if (sock->type != SOCK_STREAM) - res = tipc_set_portunreliable(tsock->p->ref, value); - else - res = -ENOPROTOOPT; - break; - case TIPC_DEST_DROPPABLE: - res = tipc_set_portunreturnable(tsock->p->ref, value); - break; - case TIPC_CONN_TIMEOUT: - sock->sk->sk_rcvtimeo = (value * HZ / 1000); - break; - default: - res = -EINVAL; - } - - up(&tsock->sem); - return res; -} - -/** - * getsockopt - get socket option - * @sock: socket structure - * @lvl: option level - * @opt: option identifier - * @ov: receptacle for option value - * @ol: receptacle for length of option value - * - * For stream sockets only, returns 0 length result for all IPPROTO_TCP options - * (to ease compatibility). - * - * Returns 0 on success, errno otherwise - */ - -static int getsockopt(struct socket *sock, int lvl, int opt, char *ov, int *ol) -{ - struct tipc_sock *tsock = tipc_sk(sock->sk); - int len; - u32 value; - int res; - - if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM)) - return put_user(0, ol); - if (lvl != SOL_TIPC) - return -ENOPROTOOPT; - if ((res = get_user(len, ol))) - return res; - - if (down_interruptible(&tsock->sem)) - return -ERESTARTSYS; - - switch (opt) { - case TIPC_IMPORTANCE: - res = tipc_portimportance(tsock->p->ref, &value); - break; - case TIPC_SRC_DROPPABLE: - res = tipc_portunreliable(tsock->p->ref, &value); - break; - case TIPC_DEST_DROPPABLE: - res = tipc_portunreturnable(tsock->p->ref, &value); - break; - case TIPC_CONN_TIMEOUT: - value = (sock->sk->sk_rcvtimeo * 1000) / HZ; - break; - default: - res = -EINVAL; - } - - if (res) { - /* "get" failed */ - } - else if (len < sizeof(value)) { - res = -EINVAL; - } - else if ((res = copy_to_user(ov, &value, sizeof(value)))) { - /* couldn't return value */ - } - else { - res = put_user(sizeof(value), ol); - } - - up(&tsock->sem); - return res; -} - -/** - * Placeholders for non-implemented functionality - * - * Returns error code (POSIX-compliant where defined) - */ - -static int ioctl(struct socket *s, u32 cmd, unsigned long arg) -{ - return -EINVAL; -} - -static int no_mmap(struct file *file, struct socket *sock, - struct vm_area_struct *vma) -{ - return -EINVAL; -} -static ssize_t no_sendpage(struct socket *sock, struct page *page, - int offset, size_t size, int flags) -{ - return -EINVAL; -} - -static int no_skpair(struct socket *s1, struct socket *s2) -{ - return -EOPNOTSUPP; -} - -/** - * Protocol switches for the various types of TIPC sockets - */ - -static struct proto_ops msg_ops = { - .owner = THIS_MODULE, - .family = AF_TIPC, - .release = release, - .bind = bind, - .connect = connect, - .socketpair = no_skpair, - .accept = accept, - .getname = get_name, - .poll = poll, - .ioctl = ioctl, - .listen = listen, - .shutdown = shutdown, - .setsockopt = setsockopt, - .getsockopt = getsockopt, - .sendmsg = send_msg, - .recvmsg = recv_msg, - .mmap = no_mmap, - .sendpage = no_sendpage -}; - -static struct proto_ops packet_ops = { - .owner = THIS_MODULE, - .family = AF_TIPC, - .release = release, - .bind = bind, - .connect = connect, - .socketpair = no_skpair, - .accept = accept, - .getname = get_name, - .poll = poll, - .ioctl = ioctl, - .listen = listen, - .shutdown = shutdown, - .setsockopt = setsockopt, - .getsockopt = getsockopt, - .sendmsg = send_packet, - .recvmsg = recv_msg, - .mmap = no_mmap, - .sendpage = no_sendpage -}; - -static struct proto_ops stream_ops = { - .owner = THIS_MODULE, - .family = AF_TIPC, - .release = release, - .bind = bind, - .connect = connect, - .socketpair = no_skpair, - .accept = accept, - .getname = get_name, - .poll = poll, - .ioctl = ioctl, - .listen = listen, - .shutdown = shutdown, - .setsockopt = setsockopt, - .getsockopt = getsockopt, - .sendmsg = send_stream, - .recvmsg = recv_stream, - .mmap = no_mmap, - .sendpage = no_sendpage -}; - -static struct net_proto_family tipc_family_ops = { - .owner = THIS_MODULE, - .family = AF_TIPC, - .create = tipc_create -}; - -static struct proto tipc_proto = { - .name = "TIPC", - .owner = THIS_MODULE, - .obj_size = sizeof(struct tipc_sock) -}; - -/** - * socket_init - initialize TIPC socket interface - * - * Returns 0 on success, errno otherwise - */ -int socket_init(void) -{ - int res; - - res = proto_register(&tipc_proto, 1); - if (res) { - err("Failed to register TIPC protocol type\n"); - goto out; - } - - res = sock_register(&tipc_family_ops); - if (res) { - err("Failed to register TIPC socket type\n"); - proto_unregister(&tipc_proto); - goto out; - } - - sockets_enabled = 1; - out: - return res; -} - -/** - * sock_stop - stop TIPC socket interface - */ -void socket_stop(void) -{ - if (!sockets_enabled) - return; - - sockets_enabled = 0; - sock_unregister(tipc_family_ops.family); - proto_unregister(&tipc_proto); -} - diff --git a/trunk/net/tipc/subscr.c b/trunk/net/tipc/subscr.c deleted file mode 100644 index 80e219ba527d..000000000000 --- a/trunk/net/tipc/subscr.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * net/tipc/subscr.c: TIPC subscription service - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "dbg.h" -#include "subscr.h" -#include "name_table.h" -#include "ref.h" - -/** - * struct subscriber - TIPC network topology subscriber - * @ref: object reference to subscriber object itself - * @lock: pointer to spinlock controlling access to subscriber object - * @subscriber_list: adjacent subscribers in top. server's list of subscribers - * @subscription_list: list of subscription objects for this subscriber - * @port_ref: object reference to port used to communicate with subscriber - * @swap: indicates if subscriber uses opposite endianness in its messages - */ - -struct subscriber { - u32 ref; - spinlock_t *lock; - struct list_head subscriber_list; - struct list_head subscription_list; - u32 port_ref; - int swap; -}; - -/** - * struct top_srv - TIPC network topology subscription service - * @user_ref: TIPC userid of subscription service - * @setup_port: reference to TIPC port that handles subscription requests - * @subscription_count: number of active subscriptions (not subscribers!) - * @subscriber_list: list of ports subscribing to service - * @lock: spinlock govering access to subscriber list - */ - -struct top_srv { - u32 user_ref; - u32 setup_port; - atomic_t subscription_count; - struct list_head subscriber_list; - spinlock_t lock; -}; - -static struct top_srv topsrv = { 0 }; - -/** - * htohl - convert value to endianness used by destination - * @in: value to convert - * @swap: non-zero if endianness must be reversed - * - * Returns converted value - */ - -static inline u32 htohl(u32 in, int swap) -{ - char *c = (char *)∈ - - return swap ? ((c[3] << 3) + (c[2] << 2) + (c[1] << 1) + c[0]) : in; -} - -/** - * subscr_send_event - send a message containing a tipc_event to the subscriber - */ - -static void subscr_send_event(struct subscription *sub, - u32 found_lower, - u32 found_upper, - u32 event, - u32 port_ref, - u32 node) -{ - struct iovec msg_sect; - - msg_sect.iov_base = (void *)&sub->evt; - msg_sect.iov_len = sizeof(struct tipc_event); - - sub->evt.event = htohl(event, sub->owner->swap); - sub->evt.found_lower = htohl(found_lower, sub->owner->swap); - sub->evt.found_upper = htohl(found_upper, sub->owner->swap); - sub->evt.port.ref = htohl(port_ref, sub->owner->swap); - sub->evt.port.node = htohl(node, sub->owner->swap); - tipc_send(sub->owner->port_ref, 1, &msg_sect); -} - -/** - * subscr_overlap - test for subscription overlap with the given values - * - * Returns 1 if there is overlap, otherwise 0. - */ - -int subscr_overlap(struct subscription *sub, - u32 found_lower, - u32 found_upper) - -{ - if (found_lower < sub->seq.lower) - found_lower = sub->seq.lower; - if (found_upper > sub->seq.upper) - found_upper = sub->seq.upper; - if (found_lower > found_upper) - return 0; - return 1; -} - -/** - * subscr_report_overlap - issue event if there is subscription overlap - * - * Protected by nameseq.lock in name_table.c - */ - -void subscr_report_overlap(struct subscription *sub, - u32 found_lower, - u32 found_upper, - u32 event, - u32 port_ref, - u32 node, - int must) -{ - dbg("Rep overlap %u:%u,%u<->%u,%u\n", sub->seq.type, sub->seq.lower, - sub->seq.upper, found_lower, found_upper); - if (!subscr_overlap(sub, found_lower, found_upper)) - return; - if (!must && (sub->filter != TIPC_SUB_PORTS)) - return; - subscr_send_event(sub, found_lower, found_upper, event, port_ref, node); -} - -/** - * subscr_timeout - subscription timeout has occurred - */ - -static void subscr_timeout(struct subscription *sub) -{ - struct subscriber *subscriber; - u32 subscriber_ref; - - /* Validate subscriber reference (in case subscriber is terminating) */ - - subscriber_ref = sub->owner->ref; - subscriber = (struct subscriber *)ref_lock(subscriber_ref); - if (subscriber == NULL) - return; - - /* Unlink subscription from name table */ - - nametbl_unsubscribe(sub); - - /* Notify subscriber of timeout, then unlink subscription */ - - subscr_send_event(sub, - sub->evt.s.seq.lower, - sub->evt.s.seq.upper, - TIPC_SUBSCR_TIMEOUT, - 0, - 0); - list_del(&sub->subscription_list); - - /* Now destroy subscription */ - - ref_unlock(subscriber_ref); - k_term_timer(&sub->timer); - kfree(sub); - atomic_dec(&topsrv.subscription_count); -} - -/** - * subscr_terminate - terminate communication with a subscriber - * - * Called with subscriber locked. Routine must temporarily release this lock - * to enable subscription timeout routine(s) to finish without deadlocking; - * the lock is then reclaimed to allow caller to release it upon return. - * (This should work even in the unlikely event some other thread creates - * a new object reference in the interim that uses this lock; this routine will - * simply wait for it to be released, then claim it.) - */ - -static void subscr_terminate(struct subscriber *subscriber) -{ - struct subscription *sub; - struct subscription *sub_temp; - - /* Invalidate subscriber reference */ - - ref_discard(subscriber->ref); - spin_unlock_bh(subscriber->lock); - - /* Destroy any existing subscriptions for subscriber */ - - list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, - subscription_list) { - if (sub->timeout != TIPC_WAIT_FOREVER) { - k_cancel_timer(&sub->timer); - k_term_timer(&sub->timer); - } - nametbl_unsubscribe(sub); - list_del(&sub->subscription_list); - dbg("Term: Removed sub %u,%u,%u from subscriber %x list\n", - sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); - kfree(sub); - atomic_dec(&topsrv.subscription_count); - } - - /* Sever connection to subscriber */ - - tipc_shutdown(subscriber->port_ref); - tipc_deleteport(subscriber->port_ref); - - /* Remove subscriber from topology server's subscriber list */ - - spin_lock_bh(&topsrv.lock); - list_del(&subscriber->subscriber_list); - spin_unlock_bh(&topsrv.lock); - - /* Now destroy subscriber */ - - spin_lock_bh(subscriber->lock); - kfree(subscriber); -} - -/** - * subscr_subscribe - create subscription for subscriber - * - * Called with subscriber locked - */ - -static void subscr_subscribe(struct tipc_subscr *s, - struct subscriber *subscriber) -{ - struct subscription *sub; - - /* Refuse subscription if global limit exceeded */ - - if (atomic_read(&topsrv.subscription_count) >= tipc_max_subscriptions) { - warn("Failed: max %u subscriptions\n", tipc_max_subscriptions); - subscr_terminate(subscriber); - return; - } - - /* Allocate subscription object */ - - sub = kmalloc(sizeof(*sub), GFP_ATOMIC); - if (sub == NULL) { - warn("Memory squeeze; ignoring subscription\n"); - subscr_terminate(subscriber); - return; - } - - /* Determine/update subscriber's endianness */ - - if ((s->filter == TIPC_SUB_PORTS) || (s->filter == TIPC_SUB_SERVICE)) - subscriber->swap = 0; - else - subscriber->swap = 1; - - /* Initialize subscription object */ - - memset(sub, 0, sizeof(*sub)); - sub->seq.type = htohl(s->seq.type, subscriber->swap); - sub->seq.lower = htohl(s->seq.lower, subscriber->swap); - sub->seq.upper = htohl(s->seq.upper, subscriber->swap); - sub->timeout = htohl(s->timeout, subscriber->swap); - sub->filter = htohl(s->filter, subscriber->swap); - if ((((sub->filter != TIPC_SUB_PORTS) - && (sub->filter != TIPC_SUB_SERVICE))) - || (sub->seq.lower > sub->seq.upper)) { - warn("Rejecting illegal subscription %u,%u,%u\n", - sub->seq.type, sub->seq.lower, sub->seq.upper); - kfree(sub); - subscr_terminate(subscriber); - return; - } - memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); - INIT_LIST_HEAD(&sub->subscription_list); - INIT_LIST_HEAD(&sub->nameseq_list); - list_add(&sub->subscription_list, &subscriber->subscription_list); - atomic_inc(&topsrv.subscription_count); - if (sub->timeout != TIPC_WAIT_FOREVER) { - k_init_timer(&sub->timer, - (Handler)subscr_timeout, (unsigned long)sub); - k_start_timer(&sub->timer, sub->timeout); - } - sub->owner = subscriber; - nametbl_subscribe(sub); -} - -/** - * subscr_conn_shutdown_event - handle termination request from subscriber - */ - -static void subscr_conn_shutdown_event(void *usr_handle, - u32 portref, - struct sk_buff **buf, - unsigned char const *data, - unsigned int size, - int reason) -{ - struct subscriber *subscriber; - spinlock_t *subscriber_lock; - - subscriber = ref_lock((u32)(unsigned long)usr_handle); - if (subscriber == NULL) - return; - - subscriber_lock = subscriber->lock; - subscr_terminate(subscriber); - spin_unlock_bh(subscriber_lock); -} - -/** - * subscr_conn_msg_event - handle new subscription request from subscriber - */ - -static void subscr_conn_msg_event(void *usr_handle, - u32 port_ref, - struct sk_buff **buf, - const unchar *data, - u32 size) -{ - struct subscriber *subscriber; - spinlock_t *subscriber_lock; - - subscriber = ref_lock((u32)(unsigned long)usr_handle); - if (subscriber == NULL) - return; - - subscriber_lock = subscriber->lock; - if (size != sizeof(struct tipc_subscr)) - subscr_terminate(subscriber); - else - subscr_subscribe((struct tipc_subscr *)data, subscriber); - - spin_unlock_bh(subscriber_lock); -} - -/** - * subscr_named_msg_event - handle request to establish a new subscriber - */ - -static void subscr_named_msg_event(void *usr_handle, - u32 port_ref, - struct sk_buff **buf, - const unchar *data, - u32 size, - u32 importance, - struct tipc_portid const *orig, - struct tipc_name_seq const *dest) -{ - struct subscriber *subscriber; - struct iovec msg_sect = {0, 0}; - spinlock_t *subscriber_lock; - - dbg("subscr_named_msg_event: orig = %x own = %x,\n", - orig->node, tipc_own_addr); - if (size && (size != sizeof(struct tipc_subscr))) { - warn("Received tipc_subscr of invalid size\n"); - return; - } - - /* Create subscriber object */ - - subscriber = kmalloc(sizeof(struct subscriber), GFP_ATOMIC); - if (subscriber == NULL) { - warn("Memory squeeze; ignoring subscriber setup\n"); - return; - } - memset(subscriber, 0, sizeof(struct subscriber)); - INIT_LIST_HEAD(&subscriber->subscription_list); - INIT_LIST_HEAD(&subscriber->subscriber_list); - subscriber->ref = ref_acquire(subscriber, &subscriber->lock); - if (subscriber->ref == 0) { - warn("Failed to acquire subscriber reference\n"); - kfree(subscriber); - return; - } - - /* Establish a connection to subscriber */ - - tipc_createport(topsrv.user_ref, - (void *)(unsigned long)subscriber->ref, - importance, - 0, - 0, - subscr_conn_shutdown_event, - 0, - 0, - subscr_conn_msg_event, - 0, - &subscriber->port_ref); - if (subscriber->port_ref == 0) { - warn("Memory squeeze; failed to create subscription port\n"); - ref_discard(subscriber->ref); - kfree(subscriber); - return; - } - tipc_connect2port(subscriber->port_ref, orig); - - - /* Add subscriber to topology server's subscriber list */ - - ref_lock(subscriber->ref); - spin_lock_bh(&topsrv.lock); - list_add(&subscriber->subscriber_list, &topsrv.subscriber_list); - spin_unlock_bh(&topsrv.lock); - - /* - * Subscribe now if message contains a subscription, - * otherwise send an empty response to complete connection handshaking - */ - - subscriber_lock = subscriber->lock; - if (size) - subscr_subscribe((struct tipc_subscr *)data, subscriber); - else - tipc_send(subscriber->port_ref, 1, &msg_sect); - - spin_unlock_bh(subscriber_lock); -} - -int subscr_start(void) -{ - struct tipc_name_seq seq = {TIPC_TOP_SRV, TIPC_TOP_SRV, TIPC_TOP_SRV}; - int res = -1; - - memset(&topsrv, 0, sizeof (topsrv)); - topsrv.lock = SPIN_LOCK_UNLOCKED; - INIT_LIST_HEAD(&topsrv.subscriber_list); - - spin_lock_bh(&topsrv.lock); - res = tipc_attach(&topsrv.user_ref, 0, 0); - if (res) { - spin_unlock_bh(&topsrv.lock); - return res; - } - - res = tipc_createport(topsrv.user_ref, - 0, - TIPC_CRITICAL_IMPORTANCE, - 0, - 0, - 0, - 0, - subscr_named_msg_event, - 0, - 0, - &topsrv.setup_port); - if (res) - goto failed; - - res = nametbl_publish_rsv(topsrv.setup_port, TIPC_NODE_SCOPE, &seq); - if (res) - goto failed; - - spin_unlock_bh(&topsrv.lock); - return 0; - -failed: - err("Failed to create subscription service\n"); - tipc_detach(topsrv.user_ref); - topsrv.user_ref = 0; - spin_unlock_bh(&topsrv.lock); - return res; -} - -void subscr_stop(void) -{ - struct subscriber *subscriber; - struct subscriber *subscriber_temp; - spinlock_t *subscriber_lock; - - if (topsrv.user_ref) { - tipc_deleteport(topsrv.setup_port); - list_for_each_entry_safe(subscriber, subscriber_temp, - &topsrv.subscriber_list, - subscriber_list) { - ref_lock(subscriber->ref); - subscriber_lock = subscriber->lock; - subscr_terminate(subscriber); - spin_unlock_bh(subscriber_lock); - } - tipc_detach(topsrv.user_ref); - topsrv.user_ref = 0; - } -} - - -int tipc_ispublished(struct tipc_name const *name) -{ - u32 domain = 0; - - return(nametbl_translate(name->type, name->instance,&domain) != 0); -} - diff --git a/trunk/net/tipc/subscr.h b/trunk/net/tipc/subscr.h deleted file mode 100644 index ccff4efcb755..000000000000 --- a/trunk/net/tipc/subscr.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * net/tipc/subscr.h: Include file for TIPC subscription service - * - * Copyright (c) 2003-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_SUBSCR_H -#define _TIPC_SUBSCR_H - -/** - * struct subscription - TIPC network topology subscription object - * @seq: name sequence associated with subscription - * @timeout: duration of subscription (in ms) - * @filter: event filtering to be done for subscription - * @evt: template for events generated by subscription - * @subscription_list: adjacent subscriptions in subscriber's subscription list - * @nameseq_list: adjacent subscriptions in name sequence's subscription list - * @timer_ref: reference to timer governing subscription duration (may be NULL) - * @owner: pointer to subscriber object associated with this subscription - */ - -struct subscription { - struct tipc_name_seq seq; - u32 timeout; - u32 filter; - struct tipc_event evt; - struct list_head subscription_list; - struct list_head nameseq_list; - struct timer_list timer; - struct subscriber *owner; -}; - -int subscr_overlap(struct subscription * sub, - u32 found_lower, - u32 found_upper); - -void subscr_report_overlap(struct subscription * sub, - u32 found_lower, - u32 found_upper, - u32 event, - u32 port_ref, - u32 node, - int must_report); - -int subscr_start(void); - -void subscr_stop(void); - - -#endif diff --git a/trunk/net/tipc/user_reg.c b/trunk/net/tipc/user_reg.c deleted file mode 100644 index 35ec7dc8211d..000000000000 --- a/trunk/net/tipc/user_reg.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * net/tipc/user_reg.c: TIPC user registry code - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2004-2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "user_reg.h" - -/* - * TIPC user registry keeps track of users of the tipc_port interface. - * - * The registry utilizes an array of "TIPC user" entries; - * a user's ID is the index of their associated array entry. - * Array entry 0 is not used, so userid 0 is not valid; - * TIPC sometimes uses this value to denote an anonymous user. - * The list of free entries is initially chained from last entry to entry 1. - */ - -/** - * struct tipc_user - registered TIPC user info - * @next: index of next free registry entry (or -1 for an allocated entry) - * @callback: ptr to routine to call when TIPC mode changes (NULL if none) - * @usr_handle: user-defined value passed to callback routine - * @ports: list of user ports owned by the user - */ - -struct tipc_user { - int next; - tipc_mode_event callback; - void *usr_handle; - struct list_head ports; -}; - -#define MAX_USERID 64 -#define USER_LIST_SIZE ((MAX_USERID + 1) * sizeof(struct tipc_user)) - -static struct tipc_user *users = 0; -static u32 next_free_user = MAX_USERID + 1; -static spinlock_t reg_lock = SPIN_LOCK_UNLOCKED; - -/** - * reg_init - create TIPC user registry (but don't activate it) - * - * If registry has been pre-initialized it is left "as is". - * NOTE: This routine may be called when TIPC is inactive. - */ - -static int reg_init(void) -{ - u32 i; - - spin_lock_bh(®_lock); - if (!users) { - users = (struct tipc_user *)kmalloc(USER_LIST_SIZE, GFP_ATOMIC); - if (users) { - memset(users, 0, USER_LIST_SIZE); - for (i = 1; i <= MAX_USERID; i++) { - users[i].next = i - 1; - } - next_free_user = MAX_USERID; - } - } - spin_unlock_bh(®_lock); - return users ? TIPC_OK : -ENOMEM; -} - -/** - * reg_callback - inform TIPC user about current operating mode - */ - -static void reg_callback(struct tipc_user *user_ptr) -{ - tipc_mode_event cb; - void *arg; - - spin_lock_bh(®_lock); - cb = user_ptr->callback; - arg = user_ptr->usr_handle; - spin_unlock_bh(®_lock); - - if (cb) - cb(arg, tipc_mode, tipc_own_addr); -} - -/** - * reg_start - activate TIPC user registry - */ - -int reg_start(void) -{ - u32 u; - int res; - - if ((res = reg_init())) - return res; - - for (u = 1; u <= MAX_USERID; u++) { - if (users[u].callback) - k_signal((Handler)reg_callback, - (unsigned long)&users[u]); - } - return TIPC_OK; -} - -/** - * reg_stop - shut down & delete TIPC user registry - */ - -void reg_stop(void) -{ - int id; - - if (!users) - return; - - for (id = 1; id <= MAX_USERID; id++) { - if (users[id].callback) - reg_callback(&users[id]); - } - kfree(users); - users = 0; -} - -/** - * tipc_attach - register a TIPC user - * - * NOTE: This routine may be called when TIPC is inactive. - */ - -int tipc_attach(u32 *userid, tipc_mode_event cb, void *usr_handle) -{ - struct tipc_user *user_ptr; - - if ((tipc_mode == TIPC_NOT_RUNNING) && !cb) - return -ENOPROTOOPT; - if (!users) - reg_init(); - - spin_lock_bh(®_lock); - if (!next_free_user) { - spin_unlock_bh(®_lock); - return -EBUSY; - } - user_ptr = &users[next_free_user]; - *userid = next_free_user; - next_free_user = user_ptr->next; - user_ptr->next = -1; - spin_unlock_bh(®_lock); - - user_ptr->callback = cb; - user_ptr->usr_handle = usr_handle; - INIT_LIST_HEAD(&user_ptr->ports); - atomic_inc(&tipc_user_count); - - if (cb && (tipc_mode != TIPC_NOT_RUNNING)) - k_signal((Handler)reg_callback, (unsigned long)user_ptr); - return TIPC_OK; -} - -/** - * tipc_detach - deregister a TIPC user - */ - -void tipc_detach(u32 userid) -{ - struct tipc_user *user_ptr; - struct list_head ports_temp; - struct user_port *up_ptr, *temp_up_ptr; - - if ((userid == 0) || (userid > MAX_USERID)) - return; - - spin_lock_bh(®_lock); - if ((!users) || (users[userid].next >= 0)) { - spin_unlock_bh(®_lock); - return; - } - - user_ptr = &users[userid]; - user_ptr->callback = NULL; - INIT_LIST_HEAD(&ports_temp); - list_splice(&user_ptr->ports, &ports_temp); - user_ptr->next = next_free_user; - next_free_user = userid; - spin_unlock_bh(®_lock); - - atomic_dec(&tipc_user_count); - - list_for_each_entry_safe(up_ptr, temp_up_ptr, &ports_temp, uport_list) { - tipc_deleteport(up_ptr->ref); - } -} - -/** - * reg_add_port - register a user's driver port - */ - -int reg_add_port(struct user_port *up_ptr) -{ - struct tipc_user *user_ptr; - - if (up_ptr->user_ref == 0) - return TIPC_OK; - if (up_ptr->user_ref > MAX_USERID) - return -EINVAL; - if ((tipc_mode == TIPC_NOT_RUNNING) || !users ) - return -ENOPROTOOPT; - - spin_lock_bh(®_lock); - user_ptr = &users[up_ptr->user_ref]; - list_add(&up_ptr->uport_list, &user_ptr->ports); - spin_unlock_bh(®_lock); - return TIPC_OK; -} - -/** - * reg_remove_port - deregister a user's driver port - */ - -int reg_remove_port(struct user_port *up_ptr) -{ - if (up_ptr->user_ref == 0) - return TIPC_OK; - if (up_ptr->user_ref > MAX_USERID) - return -EINVAL; - if (!users ) - return -ENOPROTOOPT; - - spin_lock_bh(®_lock); - list_del_init(&up_ptr->uport_list); - spin_unlock_bh(®_lock); - return TIPC_OK; -} - diff --git a/trunk/net/tipc/user_reg.h b/trunk/net/tipc/user_reg.h deleted file mode 100644 index 122ca9be3671..000000000000 --- a/trunk/net/tipc/user_reg.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * net/tipc/user_reg.h: Include file for TIPC user registry code - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_USER_REG_H -#define _TIPC_USER_REG_H - -#include "port.h" - -int reg_start(void); -void reg_stop(void); - -int reg_add_port(struct user_port *up_ptr); -int reg_remove_port(struct user_port *up_ptr); - -#endif diff --git a/trunk/net/tipc/zone.c b/trunk/net/tipc/zone.c deleted file mode 100644 index 4eaef662d568..000000000000 --- a/trunk/net/tipc/zone.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * net/tipc/zone.c: TIPC zone management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core.h" -#include "zone.h" -#include "net.h" -#include "addr.h" -#include "node_subscr.h" -#include "cluster.h" -#include "node.h" - -struct _zone *zone_create(u32 addr) -{ - struct _zone *z_ptr = 0; - u32 z_num; - - if (!addr_domain_valid(addr)) - return 0; - - z_ptr = (struct _zone *)kmalloc(sizeof(*z_ptr), GFP_ATOMIC); - if (z_ptr != NULL) { - memset(z_ptr, 0, sizeof(*z_ptr)); - z_num = tipc_zone(addr); - z_ptr->addr = tipc_addr(z_num, 0, 0); - net.zones[z_num] = z_ptr; - } - return z_ptr; -} - -void zone_delete(struct _zone *z_ptr) -{ - u32 c_num; - - if (!z_ptr) - return; - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - cluster_delete(z_ptr->clusters[c_num]); - } - kfree(z_ptr); -} - -void zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr) -{ - u32 c_num = tipc_cluster(c_ptr->addr); - - assert(c_ptr->addr); - assert(c_num <= tipc_max_clusters); - assert(z_ptr->clusters[c_num] == 0); - z_ptr->clusters[c_num] = c_ptr; -} - -void zone_remove_as_router(struct _zone *z_ptr, u32 router) -{ - u32 c_num; - - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - if (z_ptr->clusters[c_num]) { - cluster_remove_as_router(z_ptr->clusters[c_num], - router); - } - } -} - -void zone_send_external_routes(struct _zone *z_ptr, u32 dest) -{ - u32 c_num; - - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - if (z_ptr->clusters[c_num]) { - if (in_own_cluster(z_ptr->addr)) - continue; - cluster_send_ext_routes(z_ptr->clusters[c_num], dest); - } - } -} - -struct node *zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref) -{ - struct cluster *c_ptr; - struct node *n_ptr; - u32 c_num; - - if (!z_ptr) - return 0; - c_ptr = z_ptr->clusters[tipc_cluster(addr)]; - if (!c_ptr) - return 0; - n_ptr = cluster_select_node(c_ptr, ref); - if (n_ptr) - return n_ptr; - - /* Links to any other clusters within this zone ? */ - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - c_ptr = z_ptr->clusters[c_num]; - if (!c_ptr) - return 0; - n_ptr = cluster_select_node(c_ptr, ref); - if (n_ptr) - return n_ptr; - } - return 0; -} - -u32 zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref) -{ - struct cluster *c_ptr; - u32 c_num; - u32 router; - - if (!z_ptr) - return 0; - c_ptr = z_ptr->clusters[tipc_cluster(addr)]; - router = c_ptr ? cluster_select_router(c_ptr, ref) : 0; - if (router) - return router; - - /* Links to any other clusters within the zone? */ - for (c_num = 1; c_num <= tipc_max_clusters; c_num++) { - c_ptr = z_ptr->clusters[c_num]; - router = c_ptr ? cluster_select_router(c_ptr, ref) : 0; - if (router) - return router; - } - return 0; -} - - -u32 zone_next_node(u32 addr) -{ - struct cluster *c_ptr = cluster_find(addr); - - if (c_ptr) - return cluster_next_node(c_ptr, addr); - return 0; -} - diff --git a/trunk/net/tipc/zone.h b/trunk/net/tipc/zone.h deleted file mode 100644 index 4326f78d8292..000000000000 --- a/trunk/net/tipc/zone.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * net/tipc/zone.h: Include file for TIPC zone management routines - * - * Copyright (c) 2000-2006, Ericsson AB - * Copyright (c) 2005, Wind River Systems - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the names of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _TIPC_ZONE_H -#define _TIPC_ZONE_H - -#include "node_subscr.h" -#include "net.h" - - -/** - * struct _zone - TIPC zone structure - * @addr: network address of zone - * @clusters: array of pointers to all clusters within zone - * @links: (used for inter-zone communication) - */ - -struct _zone { - u32 addr; - struct cluster *clusters[2]; /* currently limited to just 1 cluster */ - u32 links; -}; - -struct node *zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref); -u32 zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref); -void zone_remove_as_router(struct _zone *z_ptr, u32 router); -void zone_send_external_routes(struct _zone *z_ptr, u32 dest); -struct _zone *zone_create(u32 addr); -void zone_delete(struct _zone *z_ptr); -void zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr); -u32 zone_next_node(u32 addr); - -static inline struct _zone *zone_find(u32 addr) -{ - return net.zones[tipc_zone(addr)]; -} - -#endif diff --git a/trunk/security/selinux/avc.c b/trunk/security/selinux/avc.c index 53d6c7bbf564..12e4fb72bf0f 100644 --- a/trunk/security/selinux/avc.c +++ b/trunk/security/selinux/avc.c @@ -494,7 +494,8 @@ static inline void avc_print_ipv6_addr(struct audit_buffer *ab, char *name1, char *name2) { if (!ipv6_addr_any(addr)) - audit_log_format(ab, " %s=" NIP6_FMT, name1, NIP6(*addr)); + audit_log_format(ab, " %s=%04x:%04x:%04x:%04x:%04x:" + "%04x:%04x:%04x", name1, NIP6(*addr)); if (port) audit_log_format(ab, " %s=%d", name2, ntohs(port)); } @@ -503,7 +504,7 @@ static inline void avc_print_ipv4_addr(struct audit_buffer *ab, u32 addr, __be16 port, char *name1, char *name2) { if (addr) - audit_log_format(ab, " %s=" NIPQUAD_FMT, name1, NIPQUAD(addr)); + audit_log_format(ab, " %s=%d.%d.%d.%d", name1, NIPQUAD(addr)); if (port) audit_log_format(ab, " %s=%d", name2, ntohs(port)); }