Remove Liunx 2.4 support for kernel datapath
This commit is contained in:
1 parent
ebe4d9f094
commit
c30c369073
71 files changed
+11
-6788
No files matched your search
@@ -12,9 +12,9 @@ The OpenFlow reference implementation includes two OpenFlow switch
|
||||
implementations:
|
||||
|
||||
- The "kernel-based switch": This divides the switch into a
|
||||
"datapath" Linux kernel module (ofdatapath.o for Linux 2.4
|
||||
or ofdatapath.ko for Linux 2.6) and a userspace program
|
||||
(ofprotocol). The kernel-based switch is faster than either of
|
||||
"datapath" Linux kernel module (ofdatapath.ko for Linux 2.6) and
|
||||
a userspace program (ofprotocol).
|
||||
The kernel-based switch is faster than either of
|
||||
the other two implementations but requires building and
|
||||
installing a kernel module, which can sometimes be
|
||||
challenging.
|
||||
@@ -114,9 +114,6 @@ software listed in the "Base Prerequisites" section above:
|
||||
the same version of GCC that was used to build that kernel
|
||||
(usually version 4.0 or later).
|
||||
|
||||
* To build a kernel module for a Linux 2.4 kernel, you need an
|
||||
earlier version of GCC, typically GCC 2.95, 3.3, or 3.4.
|
||||
|
||||
- A kernel build directory corresponding to the Linux kernel image
|
||||
the module is to run on. Under Debian and Ubuntu, for example,
|
||||
each linux-image package containing a kernel binary has a
|
||||
@@ -146,7 +143,7 @@ distribution in the ordinary way using "configure" and "make".
|
||||
% ./configure CC=gcc-4.2
|
||||
|
||||
To build the Linux kernel module, so that you can run the
|
||||
kernel-based switch, add --with-l26 or --with-l24 option, or both,
|
||||
kernel-based switch, add --with-l26 option, or both,
|
||||
to the configure script's command line. Refer to Building the
|
||||
Linux Kernel-Based Switch, below, for more information.
|
||||
|
||||
@@ -192,11 +189,9 @@ distribution in the ordinary way using "configure" and "make".
|
||||
- datapath/linux-2.6/ofdatapath_<table>.ko for each <table>
|
||||
specified on --enable-hw-tables (if any).
|
||||
|
||||
If you passed --with-l24 to configure, "make" will also build the
|
||||
If you passed --with-l26 to configure, "make" will also build the
|
||||
following kernel modules:
|
||||
|
||||
- datapath/linux-2.4/ofdatapath.o
|
||||
|
||||
- datapath/linux-2.6/ofdatapath_<table>.o for each <table>
|
||||
specified on --enable-hw-tables (if any).
|
||||
|
||||
@@ -208,10 +203,6 @@ distribution in the ordinary way using "configure" and "make".
|
||||
(Linux 2.6)
|
||||
% insmod datapath/linux-2.6/ofdatapath.ko
|
||||
|
||||
(Linux 2.4)
|
||||
% insmod datapath/linux-2.4/compat24_mod.o
|
||||
% insmod datapath/linux-2.4/ofdatapath.o
|
||||
|
||||
After you load the openflow module, you may load one hardware switch
|
||||
table module (if any were built) to enable support for that hardware
|
||||
switching table.
|
||||
@@ -233,23 +224,17 @@ Building the Linux Kernel-Based Switch
|
||||
To build the kernel module, follow the build process described above,
|
||||
but pass the location of the kernel build directory as an additional
|
||||
argument to the configure script, as described under step 1 in that
|
||||
section. Specify the location on --with-l26 for Linux 2.6, --with-l24
|
||||
for Linux 2.4. For example, to build for a running instance of Linux
|
||||
2.6:
|
||||
section. Specify the location on --with-l26 for Linux 2.6.
|
||||
For example, to build for a running instance of Linux 2.6:
|
||||
|
||||
% ./configure --with-l26=/lib/modules/`uname -r`/build
|
||||
|
||||
To build for a running instance of Linux 2.4:
|
||||
|
||||
% ./configure --with-l24=/lib/modules/`uname -r`/build
|
||||
|
||||
If you wish to build OpenFlow for an architecture other than the
|
||||
architecture used for compilation, you may specify the kernel
|
||||
architecture string using the KARCH variable when invoking the
|
||||
configure script. For example, to build OpenFlow for MIPS with Linux
|
||||
2.4:
|
||||
configure script.
|
||||
|
||||
% ./configure --with-l24=/path/to/linux-2.4 KARCH=mips
|
||||
% ./configure --with-l26=/path/to/linux-2.6 KARCH=mips
|
||||
|
||||
If you have hardware that supports accelerated OpenFlow switching, and
|
||||
you have obtained a hardware table module for your hardware and
|
||||
|
||||
@@ -90,8 +90,7 @@ Please contact us with portability-related bug reports or patches.
|
||||
The Linux kernel module is, of course, Linux-specific, and the dpctl
|
||||
utility will not be useful without the kernel module. The testing of
|
||||
the kernel module has focused on Linux 2.6.26. Linux 2.6 releases
|
||||
from 2.6.15 onward and Linux 2.4 releases from 2.4.20 onward should
|
||||
also work.
|
||||
from 2.6.15 onward should also work.
|
||||
|
||||
The userspace datapath implementation should be easy to port to
|
||||
Unix-like systems. The interface to network devices, in netdev.c, is
|
||||
|
||||
+1
-5
@@ -61,7 +61,6 @@ AC_CHECK_FUNCS([strsignal])
|
||||
AC_ARG_VAR(KARCH, [Kernel Architecture String])
|
||||
AC_SUBST(KARCH)
|
||||
OFP_CHECK_LINUX(l26, 2.6, KSRC26, L26_ENABLED)
|
||||
OFP_CHECK_LINUX(l24, 2.4, KSRC24, L24_ENABLED)
|
||||
|
||||
OFP_CHECK_DPKG_BUILDPACKAGE
|
||||
|
||||
@@ -88,9 +87,6 @@ AC_CONFIG_FILES([Makefile
|
||||
datapath/Makefile
|
||||
datapath/linux-2.6/Kbuild
|
||||
datapath/linux-2.6/Makefile
|
||||
datapath/linux-2.6/Makefile.main
|
||||
datapath/linux-2.4/Kbuild
|
||||
datapath/linux-2.4/Makefile
|
||||
datapath/linux-2.4/Makefile.main])
|
||||
datapath/linux-2.6/Makefile.main])
|
||||
|
||||
AC_OUTPUT
|
||||
@@ -2,9 +2,6 @@ SUBDIRS =
|
||||
if L26_ENABLED
|
||||
SUBDIRS += linux-2.6
|
||||
endif
|
||||
if L24_ENABLED
|
||||
SUBDIRS += linux-2.4
|
||||
endif
|
||||
|
||||
EXTRA_DIST = $(dist_headers) $(dist_sources)
|
||||
EXTRA_DIST += hwtable_dummy/Modules.mk hwtable_dummy/hwtable_dummy.c
|
||||
@@ -27,5 +24,4 @@ EXTRA_DIST += \
|
||||
AUTOMAKE_OPTIONS = -Wno-portability
|
||||
|
||||
include Modules.mk
|
||||
include linux-2.4/Modules.mk
|
||||
include linux-2.6/Modules.mk
|
||||
@@ -1,36 +0,0 @@
|
||||
/*.o.flags
|
||||
/Kbuild
|
||||
/Makefile
|
||||
/Makefile.main
|
||||
/attr.c
|
||||
/brcompat.c
|
||||
/chain.c
|
||||
/datapath.c
|
||||
/compat24.c
|
||||
/crc32.c
|
||||
/crc_t.c
|
||||
/dp_act.c
|
||||
/dp_dev.c
|
||||
/dp_notify.c
|
||||
/flow.c
|
||||
/forward.c
|
||||
/forward_t.c
|
||||
/genetlink.c
|
||||
/hwtable_dummy.c
|
||||
/kernel.c
|
||||
/kthread.c
|
||||
/netlink.c
|
||||
/nx_act.c
|
||||
/nx_act_snat.c
|
||||
/nx_msg.c
|
||||
/random32.c
|
||||
/rcupdate.c
|
||||
/sched.c
|
||||
/string.c
|
||||
/table-hash.c
|
||||
/table-linear.c
|
||||
/table-mac.c
|
||||
/table_t.c
|
||||
/unit-exports.c
|
||||
/unit.c
|
||||
/tmp
|
||||
@@ -1,88 +0,0 @@
|
||||
# -*- makefile -*-
|
||||
builddir = @abs_builddir@
|
||||
srcdir = @abs_srcdir@
|
||||
top_srcdir = @abs_top_srcdir@
|
||||
KSRC = @KSRC24@
|
||||
VERSION = @VERSION@
|
||||
BUILDNR = @BUILDNR@
|
||||
|
||||
# File Lists
|
||||
include $(srcdir)/../Modules.mk
|
||||
include $(srcdir)/Modules.mk
|
||||
include @HW_TABLES@
|
||||
|
||||
# This is somewhat hacky. We want to include our compatibility headers before
|
||||
# any header files in the kernel by the same name. Unfortunately, the only
|
||||
# mechanism the kernel provides to add cflags is the EXTRA_CFLAGS variable,
|
||||
# which gets inserted into the build command after the internal kernel CFLAGS.
|
||||
# Since our stuff needs to come first, we override the variable.
|
||||
OF_CFLAGS = -I$(srcdir)/compat-2.4/include \
|
||||
-I$(srcdir)/compat-2.4/include-$(ARCH) \
|
||||
-I$(srcdir)/compat-2.4 -I$(srcdir)/.. \
|
||||
-I$(srcdir)/../../include \
|
||||
-I$(builddir)/.. $(CFLAGS) \
|
||||
-DVERSION=\"$(VERSION)\"
|
||||
ifeq '$(BUILDNR)' '0'
|
||||
OF_CFLAGS += -DBUILDNR=\"\"
|
||||
else
|
||||
OF_CFLAGS += -DBUILDNR=\"+build$(BUILDNR)\"
|
||||
endif
|
||||
override CFLAGS := $(OF_CFLAGS)
|
||||
|
||||
# Multipart objects
|
||||
list-multi := $(patsubst %,%_mod.o,$(build_modules))
|
||||
|
||||
# Module objects that we can build
|
||||
obj-m += $(list-multi)
|
||||
|
||||
# Object Parts
|
||||
define parts_template
|
||||
$(1)_mod-objs = $$(patsubst %.c,%.o,$(notdir $($(1)_sources)))
|
||||
endef
|
||||
$(foreach module,$(build_modules),$(eval $(call parts_template,$(module))))
|
||||
|
||||
# Objects that export symbols
|
||||
export-objs = $(build_objects)
|
||||
|
||||
# Include the kernel's global Rules.make
|
||||
include $(TOPDIR)/Rules.make
|
||||
|
||||
# Link rules for multi-part objects
|
||||
define link_template
|
||||
$(1)_mod.o: $($(1)_mod-objs)
|
||||
$(LD) -r -o $$@ $($(1)_mod-objs)
|
||||
endef
|
||||
$(foreach module,$(build_modules),$(eval $(call link_template,$(module))))
|
||||
|
||||
# Build system rewrite May 2008: Bobby Holley <bh10@stanford.edu>
|
||||
#
|
||||
# A few bits and pieces of this file might be derived from Intel's e1000
|
||||
# distribution, with the following license:
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Intel PRO/1000 Linux driver
|
||||
# Copyright(c) 1999 - 2007 Intel Corporation.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
# more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# The full GNU General Public License is included in this distribution in
|
||||
# the file called "COPYING".
|
||||
#
|
||||
# Contact Information:
|
||||
# Linux NICS <linux.nics@intel.com>
|
||||
# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
#
|
||||
################################################################################
|
||||
@@ -1,9 +0,0 @@
|
||||
ifneq ($(MAKING_MODULES),1)
|
||||
# We're being called directly by running make in this directory.
|
||||
include Makefile.main
|
||||
else
|
||||
# We're being included by the Linux kernel build system
|
||||
include Kbuild
|
||||
endif
|
||||
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
# -*- makefile -*-
|
||||
builddir = @abs_builddir@
|
||||
srcdir = @abs_srcdir@
|
||||
top_srcdir = @abs_top_srcdir@
|
||||
KSRC = @KSRC24@
|
||||
VERSION = @VERSION@
|
||||
AC_CC = @CC@
|
||||
KARCH = @KARCH@
|
||||
|
||||
# File Lists
|
||||
include $(srcdir)/../Modules.mk
|
||||
include $(srcdir)/Modules.mk
|
||||
include @HW_TABLES@
|
||||
|
||||
default: $(build_links)
|
||||
$(foreach m,$(build_modules), \
|
||||
$(foreach s,$($(m)_sources), \
|
||||
$(eval $(notdir $(s)): ; ln -s $(srcdir)/../$(s) .)))
|
||||
|
||||
distclean: clean
|
||||
distdir: clean
|
||||
install:
|
||||
all: default
|
||||
check: all
|
||||
clean:
|
||||
rm -f *.o *_mod.o .*.o.flags
|
||||
for d in $(build_links); do if test -h $$d; then rm $$d; fi; done
|
||||
|
||||
ifneq (,$(KSRC))
|
||||
|
||||
ifneq ($(shell grep -c 'PATCHLEVEL = 4' $(KSRC)/Makefile),1)
|
||||
$(error Linux kernel source in $(KSRC) not 2.4)
|
||||
endif
|
||||
|
||||
ifeq (/lib/modules/$(shell uname -r)/source, $(KSRC))
|
||||
KOBJ := /lib/modules/$(shell uname -r)/build
|
||||
else
|
||||
KOBJ := $(KSRC)
|
||||
endif
|
||||
|
||||
VERSION_FILE := $(KOBJ)/include/linux/version.h
|
||||
ifeq (,$(wildcard $(VERSION_FILE)))
|
||||
$(error Linux kernel source not configured - missing version.h)
|
||||
endif
|
||||
|
||||
CONFIG_FILE := $(KSRC)/include/linux/autoconf.h
|
||||
ifeq (,$(wildcard $(CONFIG_FILE)))
|
||||
$(error Linux kernel source not configured - missing autoconf.h)
|
||||
endif
|
||||
|
||||
# Determine the Cross-compile string for the kernel, which should just be the
|
||||
# c compiler with 'gcc' removed from the end. We're obviously assuming gcc
|
||||
# here.
|
||||
CROSS_COMPILE = $(shell echo $(AC_CC) | perl -p -e 's/(.*)gcc.*/$$1/')
|
||||
|
||||
# Determine if we want to override the ARCH for the kernel
|
||||
ifneq (,$(KARCH))
|
||||
ARCH_OVERRIDE := ARCH=$(KARCH)
|
||||
else
|
||||
ARCH_OVERRIDE :=
|
||||
endif
|
||||
|
||||
.PHONY: all distclean distdir clean check
|
||||
|
||||
# Invoke the kernel build system
|
||||
all:
|
||||
$(MAKE) -C $(KSRC) $(ARCH_OVERRIDE) CROSS_COMPILE=$(CROSS_COMPILE) SUBDIRS=$(PWD) modules
|
||||
|
||||
endif # (,$(KSRC))
|
||||
@@ -1,66 +0,0 @@
|
||||
both_modules += compat24
|
||||
|
||||
compat24_sources = \
|
||||
linux-2.4/compat-2.4/attr.c \
|
||||
linux-2.4/compat-2.4/compat24.c \
|
||||
linux-2.4/compat-2.4/genetlink.c \
|
||||
linux-2.4/compat-2.4/kernel.c \
|
||||
linux-2.4/compat-2.4/kthread.c \
|
||||
linux-2.4/compat-2.4/netlink.c \
|
||||
linux-2.4/compat-2.4/random32.c \
|
||||
linux-2.4/compat-2.4/rcupdate.c \
|
||||
linux-2.4/compat-2.4/sched.c \
|
||||
linux-2.4/compat-2.4/string.c
|
||||
|
||||
compat24_headers = \
|
||||
linux-2.4/compat-2.4/compat24.h \
|
||||
linux-2.4/compat-2.4/include-arm/asm/atomic.h \
|
||||
linux-2.4/compat-2.4/include-i386/asm/atomic.h \
|
||||
linux-2.4/compat-2.4/include-mips/asm/atomic.h \
|
||||
linux-2.4/compat-2.4/include-mips/asm/barrier.h \
|
||||
linux-2.4/compat-2.4/include-mips/asm/break.h \
|
||||
linux-2.4/compat-2.4/include-mips/asm/page.h \
|
||||
linux-2.4/compat-2.4/include-mips/asm/system.h \
|
||||
linux-2.4/compat-2.4/include/asm/bug.h \
|
||||
linux-2.4/compat-2.4/include/asm/system.h \
|
||||
linux-2.4/compat-2.4/include/linux/compiler.h \
|
||||
linux-2.4/compat-2.4/include/linux/delay.h \
|
||||
linux-2.4/compat-2.4/include/linux/dmi.h \
|
||||
linux-2.4/compat-2.4/include/linux/etherdevice.h \
|
||||
linux-2.4/compat-2.4/include/linux/genetlink.h \
|
||||
linux-2.4/compat-2.4/include/linux/gfp.h \
|
||||
linux-2.4/compat-2.4/include/linux/icmp.h \
|
||||
linux-2.4/compat-2.4/include/linux/if_ether.h \
|
||||
linux-2.4/compat-2.4/include/linux/if_vlan.h \
|
||||
linux-2.4/compat-2.4/include/linux/ip.h \
|
||||
linux-2.4/compat-2.4/include/linux/ipv6.h \
|
||||
linux-2.4/compat-2.4/include/linux/jiffies.h \
|
||||
linux-2.4/compat-2.4/include/linux/kernel.h \
|
||||
linux-2.4/compat-2.4/include/linux/kthread.h \
|
||||
linux-2.4/compat-2.4/include/linux/list.h \
|
||||
linux-2.4/compat-2.4/include/linux/llc.h \
|
||||
linux-2.4/compat-2.4/include/linux/module.h \
|
||||
linux-2.4/compat-2.4/include/linux/mutex.h \
|
||||
linux-2.4/compat-2.4/include/linux/netdevice.h \
|
||||
linux-2.4/compat-2.4/include/linux/netlink.h \
|
||||
linux-2.4/compat-2.4/include/linux/random.h \
|
||||
linux-2.4/compat-2.4/include/linux/rculist.h \
|
||||
linux-2.4/compat-2.4/include/linux/rcupdate.h \
|
||||
linux-2.4/compat-2.4/include/linux/sched.h \
|
||||
linux-2.4/compat-2.4/include/linux/skbuff.h \
|
||||
linux-2.4/compat-2.4/include/linux/slab.h \
|
||||
linux-2.4/compat-2.4/include/linux/sockios.h \
|
||||
linux-2.4/compat-2.4/include/linux/spinlock.h \
|
||||
linux-2.4/compat-2.4/include/linux/string.h \
|
||||
linux-2.4/compat-2.4/include/linux/tcp.h \
|
||||
linux-2.4/compat-2.4/include/linux/time.h \
|
||||
linux-2.4/compat-2.4/include/linux/timer.h \
|
||||
linux-2.4/compat-2.4/include/linux/types.h \
|
||||
linux-2.4/compat-2.4/include/linux/udp.h \
|
||||
linux-2.4/compat-2.4/include/linux/workqueue.h \
|
||||
linux-2.4/compat-2.4/include/net/checksum.h \
|
||||
linux-2.4/compat-2.4/include/net/genetlink.h \
|
||||
linux-2.4/compat-2.4/include/net/llc_pdu.h \
|
||||
linux-2.4/compat-2.4/include/net/netlink.h
|
||||
|
||||
EXTRA_DIST += linux-2.4/compat-2.4/TODO
|
||||
@@ -1,6 +0,0 @@
|
||||
Linux kernel 2.4 specific build:
|
||||
|
||||
- Backports: compat-2.4/genetlink.c is a back-port of the
|
||||
Linux 2.6 Generic Netlink functionality. It must be loaded
|
||||
as module genetlink_mod.o before openflow_mod.o may be
|
||||
loaded.
|
||||
@@ -1,2 +0,0 @@
|
||||
* Properly port RCU to Linux 2.4. In particular we will need support
|
||||
for call_rcu to properly do flow-table updating.
|
||||
@@ -1,436 +0,0 @@
|
||||
/*
|
||||
* NETLINK Netlink attributes
|
||||
*
|
||||
* Authors: Thomas Graf <tgraf@suug.ch>
|
||||
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
static u16 nla_attr_minlen[NLA_TYPE_MAX+1] = {
|
||||
[NLA_U8] = sizeof(u8),
|
||||
[NLA_U16] = sizeof(u16),
|
||||
[NLA_U32] = sizeof(u32),
|
||||
[NLA_U64] = sizeof(u64),
|
||||
[NLA_NESTED] = NLA_HDRLEN,
|
||||
};
|
||||
|
||||
static int validate_nla(struct nlattr *nla, int maxtype,
|
||||
const struct nla_policy *policy)
|
||||
{
|
||||
const struct nla_policy *pt;
|
||||
int minlen = 0, attrlen = nla_len(nla);
|
||||
|
||||
if (nla->nla_type <= 0 || nla->nla_type > maxtype)
|
||||
return 0;
|
||||
|
||||
pt = &policy[nla->nla_type];
|
||||
|
||||
BUG_ON(pt->type > NLA_TYPE_MAX);
|
||||
|
||||
switch (pt->type) {
|
||||
case NLA_FLAG:
|
||||
if (attrlen > 0)
|
||||
return -ERANGE;
|
||||
break;
|
||||
|
||||
case NLA_NUL_STRING:
|
||||
if (pt->len)
|
||||
minlen = min_t(int, attrlen, pt->len + 1);
|
||||
else
|
||||
minlen = attrlen;
|
||||
|
||||
if (!minlen || memchr(nla_data(nla), '\0', minlen) == NULL)
|
||||
return -EINVAL;
|
||||
/* fall through */
|
||||
|
||||
case NLA_STRING:
|
||||
if (attrlen < 1)
|
||||
return -ERANGE;
|
||||
|
||||
if (pt->len) {
|
||||
char *buf = nla_data(nla);
|
||||
|
||||
if (buf[attrlen - 1] == '\0')
|
||||
attrlen--;
|
||||
|
||||
if (attrlen > pt->len)
|
||||
return -ERANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case NLA_BINARY:
|
||||
if (pt->len && attrlen > pt->len)
|
||||
return -ERANGE;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (pt->len)
|
||||
minlen = pt->len;
|
||||
else if (pt->type != NLA_UNSPEC)
|
||||
minlen = nla_attr_minlen[pt->type];
|
||||
|
||||
if (attrlen < minlen)
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_validate - Validate a stream of attributes
|
||||
* @head: head of attribute stream
|
||||
* @len: length of attribute stream
|
||||
* @maxtype: maximum attribute type to be expected
|
||||
* @policy: validation policy
|
||||
*
|
||||
* Validates all attributes in the specified attribute stream against the
|
||||
* specified policy. Attributes with a type exceeding maxtype will be
|
||||
* ignored. See documenation of struct nla_policy for more details.
|
||||
*
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int nla_validate(struct nlattr *head, int len, int maxtype,
|
||||
const struct nla_policy *policy)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int rem, err;
|
||||
|
||||
nla_for_each_attr(nla, head, len, rem) {
|
||||
err = validate_nla(nla, maxtype, policy);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_parse - Parse a stream of attributes into a tb buffer
|
||||
* @tb: destination array with maxtype+1 elements
|
||||
* @maxtype: maximum attribute type to be expected
|
||||
* @head: head of attribute stream
|
||||
* @len: length of attribute stream
|
||||
*
|
||||
* Parses a stream of attributes and stores a pointer to each attribute in
|
||||
* the tb array accessable via the attribute type. Attributes with a type
|
||||
* exceeding maxtype will be silently ignored for backwards compatibility
|
||||
* reasons. policy may be set to NULL if no validation is required.
|
||||
*
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
|
||||
const struct nla_policy *policy)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int rem, err;
|
||||
|
||||
memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
|
||||
|
||||
nla_for_each_attr(nla, head, len, rem) {
|
||||
u16 type = nla->nla_type;
|
||||
|
||||
if (type > 0 && type <= maxtype) {
|
||||
if (policy) {
|
||||
err = validate_nla(nla, maxtype, policy);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
tb[type] = nla;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(rem > 0))
|
||||
printk(KERN_WARNING "netlink: %d bytes leftover after parsing "
|
||||
"attributes.\n", rem);
|
||||
|
||||
err = 0;
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_find - Find a specific attribute in a stream of attributes
|
||||
* @head: head of attribute stream
|
||||
* @len: length of attribute stream
|
||||
* @attrtype: type of attribute to look for
|
||||
*
|
||||
* Returns the first attribute in the stream matching the specified type.
|
||||
*/
|
||||
struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int rem;
|
||||
|
||||
nla_for_each_attr(nla, head, len, rem)
|
||||
if (nla->nla_type == attrtype)
|
||||
return nla;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_strlcpy - Copy string attribute payload into a sized buffer
|
||||
* @dst: where to copy the string to
|
||||
* @src: attribute to copy the string from
|
||||
* @dstsize: size of destination buffer
|
||||
*
|
||||
* Copies at most dstsize - 1 bytes into the destination buffer.
|
||||
* The result is always a valid NUL-terminated string. Unlike
|
||||
* strlcpy the destination buffer is always padded out.
|
||||
*
|
||||
* Returns the length of the source buffer.
|
||||
*/
|
||||
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
|
||||
{
|
||||
size_t srclen = nla_len(nla);
|
||||
char *src = nla_data(nla);
|
||||
|
||||
if (srclen > 0 && src[srclen - 1] == '\0')
|
||||
srclen--;
|
||||
|
||||
if (dstsize > 0) {
|
||||
size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
|
||||
|
||||
memset(dst, 0, dstsize);
|
||||
memcpy(dst, src, len);
|
||||
}
|
||||
|
||||
return srclen;
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_memcpy - Copy a netlink attribute into another memory area
|
||||
* @dest: where to copy to memcpy
|
||||
* @src: netlink attribute to copy from
|
||||
* @count: size of the destination area
|
||||
*
|
||||
* Note: The number of bytes copied is limited by the length of
|
||||
* attribute's payload. memcpy
|
||||
*
|
||||
* Returns the number of bytes copied.
|
||||
*/
|
||||
int nla_memcpy(void *dest, struct nlattr *src, int count)
|
||||
{
|
||||
int minlen = min_t(int, count, nla_len(src));
|
||||
|
||||
memcpy(dest, nla_data(src), minlen);
|
||||
|
||||
return minlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_memcmp - Compare an attribute with sized memory area
|
||||
* @nla: netlink attribute
|
||||
* @data: memory area
|
||||
* @size: size of memory area
|
||||
*/
|
||||
int nla_memcmp(const struct nlattr *nla, const void *data,
|
||||
size_t size)
|
||||
{
|
||||
int d = nla_len(nla) - size;
|
||||
|
||||
if (d == 0)
|
||||
d = memcmp(nla_data(nla), data, size);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_strcmp - Compare a string attribute against a string
|
||||
* @nla: netlink string attribute
|
||||
* @str: another string
|
||||
*/
|
||||
int nla_strcmp(const struct nlattr *nla, const char *str)
|
||||
{
|
||||
int len = strlen(str) + 1;
|
||||
int d = nla_len(nla) - len;
|
||||
|
||||
if (d == 0)
|
||||
d = memcmp(nla_data(nla), str, len);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* __nla_reserve - reserve room for attribute on the skb
|
||||
* @skb: socket buffer to reserve room on
|
||||
* @attrtype: attribute type
|
||||
* @attrlen: length of attribute payload
|
||||
*
|
||||
* Adds a netlink attribute header to a socket buffer and reserves
|
||||
* room for the payload but does not copy it.
|
||||
*
|
||||
* The caller is responsible to ensure that the skb provides enough
|
||||
* tailroom for the attribute header and payload.
|
||||
*/
|
||||
struct nlattr *__nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
|
||||
nla = (struct nlattr *) skb_put(skb, nla_total_size(attrlen));
|
||||
nla->nla_type = attrtype;
|
||||
nla->nla_len = nla_attr_size(attrlen);
|
||||
|
||||
memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
|
||||
|
||||
return nla;
|
||||
}
|
||||
|
||||
/**
|
||||
* __nla_reserve_nohdr - reserve room for attribute without header
|
||||
* @skb: socket buffer to reserve room on
|
||||
* @attrlen: length of attribute payload
|
||||
*
|
||||
* Reserves room for attribute payload without a header.
|
||||
*
|
||||
* The caller is responsible to ensure that the skb provides enough
|
||||
* tailroom for the payload.
|
||||
*/
|
||||
void *__nla_reserve_nohdr(struct sk_buff *skb, int attrlen)
|
||||
{
|
||||
void *start;
|
||||
|
||||
start = skb_put(skb, NLA_ALIGN(attrlen));
|
||||
memset(start, 0, NLA_ALIGN(attrlen));
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_reserve - reserve room for attribute on the skb
|
||||
* @skb: socket buffer to reserve room on
|
||||
* @attrtype: attribute type
|
||||
* @attrlen: length of attribute payload
|
||||
*
|
||||
* Adds a netlink attribute header to a socket buffer and reserves
|
||||
* room for the payload but does not copy it.
|
||||
*
|
||||
* Returns NULL if the tailroom of the skb is insufficient to store
|
||||
* the attribute header and payload.
|
||||
*/
|
||||
struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
|
||||
{
|
||||
if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
|
||||
return NULL;
|
||||
|
||||
return __nla_reserve(skb, attrtype, attrlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_reserve - reserve room for attribute without header
|
||||
* @skb: socket buffer to reserve room on
|
||||
* @len: length of attribute payload
|
||||
*
|
||||
* Reserves room for attribute payload without a header.
|
||||
*
|
||||
* Returns NULL if the tailroom of the skb is insufficient to store
|
||||
* the attribute payload.
|
||||
*/
|
||||
void *nla_reserve_nohdr(struct sk_buff *skb, int attrlen)
|
||||
{
|
||||
if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
|
||||
return NULL;
|
||||
|
||||
return __nla_reserve_nohdr(skb, attrlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* __nla_put - Add a netlink attribute to a socket buffer
|
||||
* @skb: socket buffer to add attribute to
|
||||
* @attrtype: attribute type
|
||||
* @attrlen: length of attribute payload
|
||||
* @data: head of attribute payload
|
||||
*
|
||||
* The caller is responsible to ensure that the skb provides enough
|
||||
* tailroom for the attribute header and payload.
|
||||
*/
|
||||
void __nla_put(struct sk_buff *skb, int attrtype, int attrlen,
|
||||
const void *data)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
|
||||
nla = __nla_reserve(skb, attrtype, attrlen);
|
||||
memcpy(nla_data(nla), data, attrlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* __nla_put_nohdr - Add a netlink attribute without header
|
||||
* @skb: socket buffer to add attribute to
|
||||
* @attrlen: length of attribute payload
|
||||
* @data: head of attribute payload
|
||||
*
|
||||
* The caller is responsible to ensure that the skb provides enough
|
||||
* tailroom for the attribute payload.
|
||||
*/
|
||||
void __nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)
|
||||
{
|
||||
void *start;
|
||||
|
||||
start = __nla_reserve_nohdr(skb, attrlen);
|
||||
memcpy(start, data, attrlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_put - Add a netlink attribute to a socket buffer
|
||||
* @skb: socket buffer to add attribute to
|
||||
* @attrtype: attribute type
|
||||
* @attrlen: length of attribute payload
|
||||
* @data: head of attribute payload
|
||||
*
|
||||
* Returns -1 if the tailroom of the skb is insufficient to store
|
||||
* the attribute header and payload.
|
||||
*/
|
||||
int nla_put(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
|
||||
{
|
||||
if (unlikely(skb_tailroom(skb) < nla_total_size(attrlen)))
|
||||
return -1;
|
||||
|
||||
__nla_put(skb, attrtype, attrlen, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* nla_put_nohdr - Add a netlink attribute without header
|
||||
* @skb: socket buffer to add attribute to
|
||||
* @attrlen: length of attribute payload
|
||||
* @data: head of attribute payload
|
||||
*
|
||||
* Returns -1 if the tailroom of the skb is insufficient to store
|
||||
* the attribute payload.
|
||||
*/
|
||||
int nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)
|
||||
{
|
||||
if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
|
||||
return -1;
|
||||
|
||||
__nla_put_nohdr(skb, attrlen, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(nla_validate);
|
||||
EXPORT_SYMBOL(nla_parse);
|
||||
EXPORT_SYMBOL(nla_find);
|
||||
EXPORT_SYMBOL(nla_strlcpy);
|
||||
EXPORT_SYMBOL(__nla_reserve);
|
||||
EXPORT_SYMBOL(__nla_reserve_nohdr);
|
||||
EXPORT_SYMBOL(nla_reserve);
|
||||
EXPORT_SYMBOL(nla_reserve_nohdr);
|
||||
EXPORT_SYMBOL(__nla_put);
|
||||
EXPORT_SYMBOL(__nla_put_nohdr);
|
||||
EXPORT_SYMBOL(nla_put);
|
||||
EXPORT_SYMBOL(nla_put_nohdr);
|
||||
EXPORT_SYMBOL(nla_memcpy);
|
||||
EXPORT_SYMBOL(nla_memcmp);
|
||||
EXPORT_SYMBOL(nla_strcmp);
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Distributed under the terms of the GNU GPL version 2.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include "compat24.h"
|
||||
|
||||
int __init compat24_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
rcu_init();
|
||||
|
||||
err = random32_init();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
init_kthread();
|
||||
|
||||
return genl_init();
|
||||
|
||||
}
|
||||
module_init(compat24_init);
|
||||
|
||||
void __exit compat24_exit(void)
|
||||
{
|
||||
genl_exit();
|
||||
}
|
||||
module_exit(compat24_exit);
|
||||
@@ -1,13 +0,0 @@
|
||||
#ifndef __COMPAT24_H
|
||||
#define __COMPAT24_H 1
|
||||
|
||||
int genl_init(void);
|
||||
void genl_exit(void);
|
||||
|
||||
int random32_init(void);
|
||||
|
||||
void init_kthread(void);
|
||||
|
||||
void rcu_init(void);
|
||||
|
||||
#endif /* compat24.h */
|
||||
@@ -1,811 +0,0 @@
|
||||
/*
|
||||
* NETLINK Generic Netlink Family
|
||||
*
|
||||
* Authors: Jamal Hadi Salim
|
||||
* Thomas Graf <tgraf@suug.ch>
|
||||
* Johannes Berg <johannes@sipsolutions.net>
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/genetlink.h>
|
||||
|
||||
#include "compat24.h"
|
||||
|
||||
struct sock *genl_sock = NULL;
|
||||
|
||||
static DECLARE_MUTEX(genl_mutex); /* serialization of message processing */
|
||||
|
||||
static void genl_lock(void)
|
||||
{
|
||||
down(&genl_mutex);
|
||||
}
|
||||
|
||||
static int genl_trylock(void)
|
||||
{
|
||||
return down_trylock(&genl_mutex);
|
||||
}
|
||||
|
||||
static void genl_unlock(void)
|
||||
{
|
||||
up(&genl_mutex);
|
||||
|
||||
if (genl_sock && genl_sock->receive_queue.qlen)
|
||||
genl_sock->data_ready(genl_sock, 0);
|
||||
}
|
||||
|
||||
#define GENL_FAM_TAB_SIZE 16
|
||||
#define GENL_FAM_TAB_MASK (GENL_FAM_TAB_SIZE - 1)
|
||||
|
||||
static struct list_head family_ht[GENL_FAM_TAB_SIZE];
|
||||
/*
|
||||
* Bitmap of multicast groups that are currently in use.
|
||||
*
|
||||
* To avoid an allocation at boot of just one unsigned long,
|
||||
* declare it global instead.
|
||||
* Bit 0 is marked as already used since group 0 is invalid.
|
||||
*/
|
||||
static unsigned long mc_group_start = 0x1;
|
||||
static unsigned long *mc_groups = &mc_group_start;
|
||||
static unsigned long mc_groups_longs = 1;
|
||||
|
||||
static int genl_ctrl_event(int event, void *data);
|
||||
|
||||
static inline unsigned int genl_family_hash(unsigned int id)
|
||||
{
|
||||
return id & GENL_FAM_TAB_MASK;
|
||||
}
|
||||
|
||||
static inline struct list_head *genl_family_chain(unsigned int id)
|
||||
{
|
||||
return &family_ht[genl_family_hash(id)];
|
||||
}
|
||||
|
||||
static struct genl_family *genl_family_find_byid(unsigned int id)
|
||||
{
|
||||
struct genl_family *f;
|
||||
|
||||
list_for_each_entry(f, genl_family_chain(id), family_list)
|
||||
if (f->id == id)
|
||||
return f;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct genl_family *genl_family_find_byname(char *name)
|
||||
{
|
||||
struct genl_family *f;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
|
||||
list_for_each_entry(f, genl_family_chain(i), family_list)
|
||||
if (strcmp(f->name, name) == 0)
|
||||
return f;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
|
||||
{
|
||||
struct genl_ops *ops;
|
||||
|
||||
list_for_each_entry(ops, &family->ops_list, ops_list)
|
||||
if (ops->cmd == cmd)
|
||||
return ops;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Of course we are going to have problems once we hit
|
||||
* 2^16 alive types, but that can only happen by year 2K
|
||||
*/
|
||||
static inline u16 genl_generate_id(void)
|
||||
{
|
||||
static u16 id_gen_idx;
|
||||
int overflowed = 0;
|
||||
|
||||
do {
|
||||
if (id_gen_idx == 0)
|
||||
id_gen_idx = GENL_MIN_ID;
|
||||
|
||||
if (++id_gen_idx > GENL_MAX_ID) {
|
||||
if (!overflowed) {
|
||||
overflowed = 1;
|
||||
id_gen_idx = 0;
|
||||
continue;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
} while (genl_family_find_byid(id_gen_idx));
|
||||
|
||||
return id_gen_idx;
|
||||
}
|
||||
|
||||
static struct genl_multicast_group notify_grp;
|
||||
|
||||
/**
|
||||
* genl_register_mc_group - register a multicast group
|
||||
*
|
||||
* Registers the specified multicast group and notifies userspace
|
||||
* about the new group.
|
||||
*
|
||||
* Returns 0 on success or a negative error code.
|
||||
*
|
||||
* @family: The generic netlink family the group shall be registered for.
|
||||
* @grp: The group to register, must have a name.
|
||||
*/
|
||||
int genl_register_mc_group(struct genl_family *family,
|
||||
struct genl_multicast_group *grp)
|
||||
{
|
||||
int id;
|
||||
|
||||
BUG_ON(grp->name[0] == '\0');
|
||||
|
||||
genl_lock();
|
||||
|
||||
/* special-case our own group */
|
||||
if (grp == ¬ify_grp)
|
||||
id = GENL_ID_CTRL;
|
||||
else
|
||||
id = find_first_zero_bit(mc_groups,
|
||||
mc_groups_longs * BITS_PER_LONG);
|
||||
|
||||
|
||||
if (id >= mc_groups_longs * BITS_PER_LONG) {
|
||||
genl_unlock();
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
grp->id = id;
|
||||
set_bit(id, mc_groups);
|
||||
list_add_tail(&grp->list, &family->mcast_groups);
|
||||
grp->family = family;
|
||||
|
||||
genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, grp);
|
||||
genl_unlock();
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(genl_register_mc_group);
|
||||
|
||||
static void __genl_unregister_mc_group(struct genl_family *family,
|
||||
struct genl_multicast_group *grp)
|
||||
{
|
||||
BUG_ON(grp->family != family);
|
||||
|
||||
/* We should clear this multicast group from any subscribers, but 2.4
|
||||
* doesn't have the proper interface to do it, and we'd need a patch to
|
||||
* implement it. */
|
||||
/*netlink_clear_multicast_users(genl_sock, grp->id);*/
|
||||
clear_bit(grp->id, mc_groups);
|
||||
list_del(&grp->list);
|
||||
genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp);
|
||||
grp->id = 0;
|
||||
grp->family = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* genl_unregister_mc_group - unregister a multicast group
|
||||
*
|
||||
* Unregisters the specified multicast group and notifies userspace
|
||||
* about it. All current listeners on the group are removed.
|
||||
*
|
||||
* Note: It is not necessary to unregister all multicast groups before
|
||||
* unregistering the family, unregistering the family will cause
|
||||
* all assigned multicast groups to be unregistered automatically.
|
||||
*
|
||||
* @family: Generic netlink family the group belongs to.
|
||||
* @grp: The group to unregister, must have been registered successfully
|
||||
* previously.
|
||||
*/
|
||||
void genl_unregister_mc_group(struct genl_family *family,
|
||||
struct genl_multicast_group *grp)
|
||||
{
|
||||
genl_lock();
|
||||
__genl_unregister_mc_group(family, grp);
|
||||
genl_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(genl_unregister_mc_group);
|
||||
|
||||
static void genl_unregister_mc_groups(struct genl_family *family)
|
||||
{
|
||||
struct genl_multicast_group *grp, *tmp;
|
||||
|
||||
genl_lock();
|
||||
list_for_each_entry_safe(grp, tmp, &family->mcast_groups, list)
|
||||
__genl_unregister_mc_group(family, grp);
|
||||
genl_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* genl_register_ops - register generic netlink operations
|
||||
* @family: generic netlink family
|
||||
* @ops: operations to be registered
|
||||
*
|
||||
* Registers the specified operations and assigns them to the specified
|
||||
* family. Either a doit or dumpit callback must be specified or the
|
||||
* operation will fail. Only one operation structure per command
|
||||
* identifier may be registered.
|
||||
*
|
||||
* See include/net/genetlink.h for more documenation on the operations
|
||||
* structure.
|
||||
*
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
|
||||
if (ops->dumpit == NULL && ops->doit == NULL)
|
||||
goto errout;
|
||||
|
||||
if (genl_get_cmd(ops->cmd, family)) {
|
||||
err = -EEXIST;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (ops->dumpit)
|
||||
ops->flags |= GENL_CMD_CAP_DUMP;
|
||||
if (ops->doit)
|
||||
ops->flags |= GENL_CMD_CAP_DO;
|
||||
if (ops->policy)
|
||||
ops->flags |= GENL_CMD_CAP_HASPOL;
|
||||
|
||||
genl_lock();
|
||||
list_add_tail(&ops->ops_list, &family->ops_list);
|
||||
genl_unlock();
|
||||
|
||||
genl_ctrl_event(CTRL_CMD_NEWOPS, ops);
|
||||
err = 0;
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* genl_unregister_ops - unregister generic netlink operations
|
||||
* @family: generic netlink family
|
||||
* @ops: operations to be unregistered
|
||||
*
|
||||
* Unregisters the specified operations and unassigns them from the
|
||||
* specified family. The operation blocks until the current message
|
||||
* processing has finished and doesn't start again until the
|
||||
* unregister process has finished.
|
||||
*
|
||||
* Note: It is not necessary to unregister all operations before
|
||||
* unregistering the family, unregistering the family will cause
|
||||
* all assigned operations to be unregistered automatically.
|
||||
*
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
|
||||
{
|
||||
struct genl_ops *rc;
|
||||
|
||||
genl_lock();
|
||||
list_for_each_entry(rc, &family->ops_list, ops_list) {
|
||||
if (rc == ops) {
|
||||
list_del(&ops->ops_list);
|
||||
genl_unlock();
|
||||
genl_ctrl_event(CTRL_CMD_DELOPS, ops);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
genl_unlock();
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* genl_register_family - register a generic netlink family
|
||||
* @family: generic netlink family
|
||||
*
|
||||
* Registers the specified family after validating it first. Only one
|
||||
* family may be registered with the same family name or identifier.
|
||||
* The family id may equal GENL_ID_GENERATE causing an unique id to
|
||||
* be automatically generated and assigned.
|
||||
*
|
||||
* Return 0 on success or a negative error code.
|
||||
*/
|
||||
int genl_register_family(struct genl_family *family)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
|
||||
if (family->id && family->id < GENL_MIN_ID)
|
||||
goto errout;
|
||||
|
||||
if (family->id > GENL_MAX_ID)
|
||||
goto errout;
|
||||
|
||||
INIT_LIST_HEAD(&family->ops_list);
|
||||
INIT_LIST_HEAD(&family->mcast_groups);
|
||||
|
||||
genl_lock();
|
||||
|
||||
if (genl_family_find_byname(family->name)) {
|
||||
err = -EEXIST;
|
||||
goto errout_locked;
|
||||
}
|
||||
|
||||
if (genl_family_find_byid(family->id)) {
|
||||
err = -EEXIST;
|
||||
goto errout_locked;
|
||||
}
|
||||
|
||||
if (family->id == GENL_ID_GENERATE) {
|
||||
u16 newid = genl_generate_id();
|
||||
|
||||
if (!newid) {
|
||||
err = -ENOMEM;
|
||||
goto errout_locked;
|
||||
}
|
||||
|
||||
family->id = newid;
|
||||
}
|
||||
|
||||
if (family->maxattr) {
|
||||
family->attrbuf = kmalloc((family->maxattr+1) *
|
||||
sizeof(struct nlattr *), GFP_KERNEL);
|
||||
if (family->attrbuf == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto errout_locked;
|
||||
}
|
||||
} else
|
||||
family->attrbuf = NULL;
|
||||
|
||||
list_add_tail(&family->family_list, genl_family_chain(family->id));
|
||||
MOD_INC_USE_COUNT;
|
||||
genl_unlock();
|
||||
|
||||
genl_ctrl_event(CTRL_CMD_NEWFAMILY, family);
|
||||
|
||||
return 0;
|
||||
|
||||
errout_locked:
|
||||
genl_unlock();
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* genl_unregister_family - unregister generic netlink family
|
||||
* @family: generic netlink family
|
||||
*
|
||||
* Unregisters the specified family.
|
||||
*
|
||||
* Returns 0 on success or a negative error code.
|
||||
*/
|
||||
int genl_unregister_family(struct genl_family *family)
|
||||
{
|
||||
struct genl_family *rc;
|
||||
|
||||
genl_unregister_mc_groups(family);
|
||||
|
||||
genl_lock();
|
||||
|
||||
list_for_each_entry(rc, genl_family_chain(family->id), family_list) {
|
||||
if (family->id != rc->id || strcmp(rc->name, family->name))
|
||||
continue;
|
||||
|
||||
list_del(&rc->family_list);
|
||||
INIT_LIST_HEAD(&family->ops_list);
|
||||
genl_unlock();
|
||||
|
||||
kfree(family->attrbuf);
|
||||
genl_ctrl_event(CTRL_CMD_DELFAMILY, family);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MOD_DEC_USE_COUNT;
|
||||
genl_unlock();
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int null_done_func(struct netlink_callback *cb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
|
||||
{
|
||||
struct genl_ops *ops;
|
||||
struct genl_family *family;
|
||||
struct genl_info info;
|
||||
struct genlmsghdr *hdr = nlmsg_data(nlh);
|
||||
int hdrlen, err;
|
||||
|
||||
family = genl_family_find_byid(nlh->nlmsg_type);
|
||||
if (family == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
hdrlen = GENL_HDRLEN + family->hdrsize;
|
||||
if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
|
||||
return -EINVAL;
|
||||
|
||||
ops = genl_get_cmd(hdr->cmd, family);
|
||||
if (ops == NULL)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if ((ops->flags & GENL_ADMIN_PERM) && !capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (nlh->nlmsg_flags & NLM_F_DUMP) {
|
||||
if (ops->dumpit == NULL)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return netlink_dump_start(genl_sock, skb, nlh,
|
||||
ops->dumpit,
|
||||
ops->done ?: null_done_func);
|
||||
}
|
||||
|
||||
if (ops->doit == NULL)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (family->attrbuf) {
|
||||
err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr,
|
||||
ops->policy);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
info.snd_seq = nlh->nlmsg_seq;
|
||||
info.snd_pid = NETLINK_CB(skb).pid;
|
||||
info.nlhdr = nlh;
|
||||
info.genlhdr = nlmsg_data(nlh);
|
||||
info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
|
||||
info.attrs = family->attrbuf;
|
||||
|
||||
return ops->doit(skb, &info);
|
||||
}
|
||||
|
||||
static void genl_rcv(struct sock *sk, int len)
|
||||
{
|
||||
unsigned int qlen = 0;
|
||||
|
||||
do {
|
||||
if (genl_trylock())
|
||||
return;
|
||||
netlink_run_queue(sk, &qlen, genl_rcv_msg);
|
||||
genl_unlock();
|
||||
} while (qlen && genl_sock && genl_sock->receive_queue.qlen);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Controller
|
||||
**************************************************************************/
|
||||
|
||||
static struct genl_family genl_ctrl = {
|
||||
.id = GENL_ID_CTRL,
|
||||
.name = "nlctrl",
|
||||
.version = 0x2,
|
||||
.maxattr = CTRL_ATTR_MAX,
|
||||
};
|
||||
|
||||
static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
|
||||
u32 flags, struct sk_buff *skb, u8 cmd)
|
||||
{
|
||||
void *hdr;
|
||||
|
||||
hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd);
|
||||
if (hdr == NULL)
|
||||
return -1;
|
||||
|
||||
NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name);
|
||||
NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id);
|
||||
NLA_PUT_U32(skb, CTRL_ATTR_VERSION, family->version);
|
||||
NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize);
|
||||
NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr);
|
||||
|
||||
if (!list_empty(&family->ops_list)) {
|
||||
struct nlattr *nla_ops;
|
||||
struct genl_ops *ops;
|
||||
int idx = 1;
|
||||
|
||||
nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS);
|
||||
if (nla_ops == NULL)
|
||||
goto nla_put_failure;
|
||||
|
||||
list_for_each_entry(ops, &family->ops_list, ops_list) {
|
||||
struct nlattr *nest;
|
||||
|
||||
nest = nla_nest_start(skb, idx++);
|
||||
if (nest == NULL)
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd);
|
||||
NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags);
|
||||
|
||||
nla_nest_end(skb, nest);
|
||||
}
|
||||
|
||||
nla_nest_end(skb, nla_ops);
|
||||
}
|
||||
|
||||
if (!list_empty(&family->mcast_groups)) {
|
||||
struct genl_multicast_group *grp;
|
||||
struct nlattr *nla_grps;
|
||||
int idx = 1;
|
||||
|
||||
nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
|
||||
if (nla_grps == NULL)
|
||||
goto nla_put_failure;
|
||||
|
||||
list_for_each_entry(grp, &family->mcast_groups, list) {
|
||||
struct nlattr *nest;
|
||||
|
||||
nest = nla_nest_start(skb, idx++);
|
||||
if (nest == NULL)
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id);
|
||||
NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME,
|
||||
grp->name);
|
||||
|
||||
nla_nest_end(skb, nest);
|
||||
}
|
||||
nla_nest_end(skb, nla_grps);
|
||||
}
|
||||
|
||||
return genlmsg_end(skb, hdr);
|
||||
|
||||
nla_put_failure:
|
||||
return genlmsg_cancel(skb, hdr);
|
||||
}
|
||||
|
||||
static int ctrl_fill_mcgrp_info(struct genl_multicast_group *grp, u32 pid,
|
||||
u32 seq, u32 flags, struct sk_buff *skb,
|
||||
u8 cmd)
|
||||
{
|
||||
void *hdr;
|
||||
struct nlattr *nla_grps;
|
||||
struct nlattr *nest;
|
||||
|
||||
hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd);
|
||||
if (hdr == NULL)
|
||||
return -1;
|
||||
|
||||
NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, grp->family->name);
|
||||
NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, grp->family->id);
|
||||
|
||||
nla_grps = nla_nest_start(skb, CTRL_ATTR_MCAST_GROUPS);
|
||||
if (nla_grps == NULL)
|
||||
goto nla_put_failure;
|
||||
|
||||
nest = nla_nest_start(skb, 1);
|
||||
if (nest == NULL)
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U32(skb, CTRL_ATTR_MCAST_GRP_ID, grp->id);
|
||||
NLA_PUT_STRING(skb, CTRL_ATTR_MCAST_GRP_NAME,
|
||||
grp->name);
|
||||
|
||||
nla_nest_end(skb, nest);
|
||||
nla_nest_end(skb, nla_grps);
|
||||
|
||||
return genlmsg_end(skb, hdr);
|
||||
|
||||
nla_put_failure:
|
||||
return genlmsg_cancel(skb, hdr);
|
||||
}
|
||||
|
||||
static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
|
||||
int i, n = 0;
|
||||
struct genl_family *rt;
|
||||
int chains_to_skip = cb->args[0];
|
||||
int fams_to_skip = cb->args[1];
|
||||
|
||||
if (chains_to_skip != 0)
|
||||
genl_lock();
|
||||
|
||||
for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
|
||||
if (i < chains_to_skip)
|
||||
continue;
|
||||
n = 0;
|
||||
list_for_each_entry(rt, genl_family_chain(i), family_list) {
|
||||
if (++n < fams_to_skip)
|
||||
continue;
|
||||
if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid,
|
||||
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
||||
skb, CTRL_CMD_NEWFAMILY) < 0)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
fams_to_skip = 0;
|
||||
}
|
||||
|
||||
errout:
|
||||
if (chains_to_skip != 0)
|
||||
genl_unlock();
|
||||
|
||||
cb->args[0] = i;
|
||||
cb->args[1] = n;
|
||||
|
||||
return skb->len;
|
||||
}
|
||||
|
||||
static struct sk_buff *ctrl_build_family_msg(struct genl_family *family,
|
||||
u32 pid, int seq, u8 cmd)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (skb == NULL)
|
||||
return ERR_PTR(-ENOBUFS);
|
||||
|
||||
err = ctrl_fill_info(family, pid, seq, 0, skb, cmd);
|
||||
if (err < 0) {
|
||||
nlmsg_free(skb);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *ctrl_build_mcgrp_msg(struct genl_multicast_group *grp,
|
||||
u32 pid, int seq, u8 cmd)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (skb == NULL)
|
||||
return ERR_PTR(-ENOBUFS);
|
||||
|
||||
err = ctrl_fill_mcgrp_info(grp, pid, seq, 0, skb, cmd);
|
||||
if (err < 0) {
|
||||
nlmsg_free(skb);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
|
||||
[CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
|
||||
[CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
|
||||
.len = GENL_NAMSIZ - 1 },
|
||||
};
|
||||
|
||||
static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
struct genl_family *res = NULL;
|
||||
int err = -EINVAL;
|
||||
|
||||
if (info->attrs[CTRL_ATTR_FAMILY_ID]) {
|
||||
u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]);
|
||||
res = genl_family_find_byid(id);
|
||||
}
|
||||
|
||||
if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
|
||||
char *name;
|
||||
|
||||
name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]);
|
||||
res = genl_family_find_byname(name);
|
||||
}
|
||||
|
||||
if (res == NULL) {
|
||||
err = -ENOENT;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
msg = ctrl_build_family_msg(res, info->snd_pid, info->snd_seq,
|
||||
CTRL_CMD_NEWFAMILY);
|
||||
if (IS_ERR(msg)) {
|
||||
err = PTR_ERR(msg);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
err = genlmsg_reply(msg, info);
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int genl_ctrl_event(int event, void *data)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
|
||||
if (genl_sock == NULL)
|
||||
return 0;
|
||||
|
||||
switch (event) {
|
||||
case CTRL_CMD_NEWFAMILY:
|
||||
case CTRL_CMD_DELFAMILY:
|
||||
msg = ctrl_build_family_msg(data, 0, 0, event);
|
||||
if (IS_ERR(msg))
|
||||
return PTR_ERR(msg);
|
||||
|
||||
genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
|
||||
break;
|
||||
case CTRL_CMD_NEWMCAST_GRP:
|
||||
case CTRL_CMD_DELMCAST_GRP:
|
||||
msg = ctrl_build_mcgrp_msg(data, 0, 0, event);
|
||||
if (IS_ERR(msg))
|
||||
return PTR_ERR(msg);
|
||||
|
||||
genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct genl_ops genl_ctrl_ops = {
|
||||
.cmd = CTRL_CMD_GETFAMILY,
|
||||
.doit = ctrl_getfamily,
|
||||
.dumpit = ctrl_dumpfamily,
|
||||
.policy = ctrl_policy,
|
||||
};
|
||||
|
||||
static struct genl_multicast_group notify_grp = {
|
||||
.name = "notify",
|
||||
};
|
||||
|
||||
int __init genl_init(void)
|
||||
{
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i < GENL_FAM_TAB_SIZE; i++)
|
||||
INIT_LIST_HEAD(&family_ht[i]);
|
||||
|
||||
err = genl_register_family(&genl_ctrl);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops);
|
||||
if (err < 0)
|
||||
goto errout_register;
|
||||
|
||||
netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
|
||||
genl_sock = netlink_kernel_create(NETLINK_GENERIC, genl_rcv);
|
||||
if (genl_sock == NULL)
|
||||
panic("GENL: Cannot initialize generic netlink\n");
|
||||
|
||||
err = genl_register_mc_group(&genl_ctrl, ¬ify_grp);
|
||||
if (err < 0)
|
||||
goto errout_register;
|
||||
|
||||
return 0;
|
||||
|
||||
errout_register:
|
||||
genl_unregister_family(&genl_ctrl);
|
||||
errout:
|
||||
panic("GENL: Cannot register controller: %d\n", err);
|
||||
}
|
||||
|
||||
void __exit genl_exit(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = genl_unregister_ops(&genl_ctrl, &genl_ctrl_ops);
|
||||
if (err) {
|
||||
printk("GENL: cannot unregister ops (%d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
err = genl_unregister_family(&genl_ctrl);
|
||||
if (err) {
|
||||
printk("GENL: cannot unregister family (%d)\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(genl_sock);
|
||||
EXPORT_SYMBOL(genl_register_ops);
|
||||
EXPORT_SYMBOL(genl_unregister_ops);
|
||||
EXPORT_SYMBOL(genl_register_family);
|
||||
EXPORT_SYMBOL(genl_unregister_family);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef __ASM_ARM_ATOMIC_H_WRAPPER
|
||||
#define __ASM_ARM_ATOMIC_H_WRAPPER 1
|
||||
|
||||
#include_next <asm/atomic.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#if __LINUX_ARM_ARCH__ >= 6
|
||||
|
||||
static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
|
||||
{
|
||||
unsigned long oldval, res;
|
||||
|
||||
do {
|
||||
__asm__ __volatile__("@ atomic_cmpxchg\n"
|
||||
"ldrex %1, [%2]\n"
|
||||
"mov %0, #0\n"
|
||||
"teq %1, %3\n"
|
||||
"strexeq %0, %4, [%2]\n"
|
||||
: "=&r" (res), "=&r" (oldval)
|
||||
: "r" (&ptr->counter), "Ir" (old), "r" (new)
|
||||
: "cc");
|
||||
} while (res);
|
||||
|
||||
return oldval;
|
||||
}
|
||||
|
||||
#else /* ARM_ARCH_6 */
|
||||
|
||||
#include <asm/system.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#error SMP not supported on pre-ARMv6 CPUs
|
||||
#endif
|
||||
|
||||
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
ret = v->counter;
|
||||
if (likely(ret == old))
|
||||
v->counter = new;
|
||||
local_irq_restore(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __LINUX_ARM_ARCH__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* asm/atomic.h */
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef __ASM_I386_ATOMIC_WRAPPER_H
|
||||
#define __ASM_I386_ATOMIC_WRAPPER_H 1
|
||||
|
||||
#include_next <asm/atomic.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
|
||||
#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
|
||||
|
||||
#endif /* atomic.h */
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef __ASM_MIPS_ATOMIC_H_WRAPPER
|
||||
#define __ASM_MIPS_ATOMIC_H_WRAPPER 1
|
||||
|
||||
#include_next <asm/atomic.h>
|
||||
|
||||
#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
|
||||
|
||||
#endif /* asm/atomic.h */
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef __ASM_MIPS_BARRIER_H_WRAPPER
|
||||
#define __ASM_MIPS_BARRIER_H_WRAPPER 1
|
||||
|
||||
#include <asm/system.h>
|
||||
|
||||
/* Not sure whether these really need to be defined, but the conservative
|
||||
* choice seems to be to define them. */
|
||||
#define CONFIG_WEAK_ORDERING 1
|
||||
#define CONFIG_WEAK_REORDERING_BEYOND_LLSC 1
|
||||
|
||||
#if defined(CONFIG_WEAK_ORDERING) && defined(CONFIG_SMP)
|
||||
#define __WEAK_ORDERING_MB " sync \n"
|
||||
#else
|
||||
#define __WEAK_ORDERING_MB " \n"
|
||||
#endif
|
||||
#if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP)
|
||||
#define __WEAK_LLSC_MB " sync \n"
|
||||
#else
|
||||
#define __WEAK_LLSC_MB " \n"
|
||||
#endif
|
||||
|
||||
#define smp_mb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
|
||||
#define smp_rmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
|
||||
#define smp_wmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
|
||||
|
||||
|
||||
#endif /* asm/barrier.h */
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef __ASM_MIPS_BREAK_H_WRAPPER
|
||||
#define __ASM_MIPS_BREAK_H_WRAPPER 1
|
||||
|
||||
#include <linux/version.h>
|
||||
#include_next <asm/break.h>
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25)
|
||||
|
||||
/*
|
||||
* The following break codes are or were in use for specific purposes in
|
||||
* other MIPS operating systems. Linux/MIPS doesn't use all of them. The
|
||||
* unused ones are here as placeholders; we might encounter them in
|
||||
* non-Linux/MIPS object files or make use of them in the future.
|
||||
*/
|
||||
#define BRK_USERBP 0 /* User bp (used by debuggers) */
|
||||
#define BRK_KERNELBP 1 /* Break in the kernel */
|
||||
#define BRK_ABORT 2 /* Sometimes used by abort(3) to SIGIOT */
|
||||
#define BRK_BD_TAKEN 3 /* For bd slot emulation - not implemented */
|
||||
#define BRK_BD_NOTTAKEN 4 /* For bd slot emulation - not implemented */
|
||||
#define BRK_SSTEPBP 5 /* User bp (used by debuggers) */
|
||||
#define BRK_OVERFLOW 6 /* Overflow check */
|
||||
#define BRK_DIVZERO 7 /* Divide by zero check */
|
||||
#define BRK_RANGE 8 /* Range error check */
|
||||
#define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */
|
||||
#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */
|
||||
#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */
|
||||
#define BRK_MULOVF 1023 /* Multiply overflow */
|
||||
#define BRK_BUG 512 /* Used by BUG() */
|
||||
|
||||
#endif /* linux kernel < 2.4.25 */
|
||||
|
||||
#endif /* asm/break.h */
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef __ASM_MIPS_PAGE_H_WRAPPER
|
||||
#define __ASM_MIPS_PAGE_H_WRAPPER 1
|
||||
|
||||
#include <linux/version.h>
|
||||
#include_next <asm/page.h>
|
||||
#include <asm/break.h>
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25)
|
||||
|
||||
#define BUG() \
|
||||
do { \
|
||||
__asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* linux kernel < 2.4.25 */
|
||||
|
||||
#endif /* asm/page.h */
|
||||
@@ -1,301 +0,0 @@
|
||||
#ifndef __ASM_MIPS_SYSTEM_H_WRAPPER
|
||||
#define __ASM_MIPS_SYSTEM_H_WRAPPER 1
|
||||
|
||||
#include_next <asm/system.h>
|
||||
|
||||
#define __HAVE_ARCH_CMPXCHG 1
|
||||
|
||||
static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
|
||||
unsigned long new)
|
||||
{
|
||||
__u32 retval;
|
||||
|
||||
#ifdef JIANGZHU_DEV
|
||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set noat \n"
|
||||
" .set mips3 \n"
|
||||
"1: ll %0, %2 # __cmpxchg_u32 \n"
|
||||
" bne %0, %z3, 2f \n"
|
||||
" .set mips0 \n"
|
||||
" move $1, %z4 \n"
|
||||
" .set mips3 \n"
|
||||
" sc $1, %1 \n"
|
||||
" beqzl $1, 1b \n"
|
||||
"2: \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (retval), "=R" (*m)
|
||||
: "R" (*m), "Jr" (old), "Jr" (new)
|
||||
: "memory");
|
||||
} else if (cpu_has_llsc) {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set noat \n"
|
||||
" .set mips3 \n"
|
||||
"1: ll %0, %2 # __cmpxchg_u32 \n"
|
||||
" bne %0, %z3, 2f \n"
|
||||
" .set mips0 \n"
|
||||
" move $1, %z4 \n"
|
||||
" .set mips3 \n"
|
||||
" sc $1, %1 \n"
|
||||
" beqz $1, 3f \n"
|
||||
"2: \n"
|
||||
" .subsection 2 \n"
|
||||
"3: b 1b \n"
|
||||
" .previous \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (retval), "=R" (*m)
|
||||
: "R" (*m), "Jr" (old), "Jr" (new)
|
||||
: "memory");
|
||||
} else {
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
if (retval == old)
|
||||
*m = new;
|
||||
local_irq_restore(flags); /* implies memory barrier */
|
||||
}
|
||||
#endif
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
if (retval == old)
|
||||
*m = new;
|
||||
local_irq_restore(flags); /* implies memory barrier */
|
||||
|
||||
/* smp_llsc_mb(); */
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline unsigned long __cmpxchg_u32_local(volatile int * m,
|
||||
unsigned long old, unsigned long new)
|
||||
{
|
||||
__u32 retval;
|
||||
|
||||
#ifdef JIANGZHU_DEV
|
||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set noat \n"
|
||||
" .set mips3 \n"
|
||||
"1: ll %0, %2 # __cmpxchg_u32 \n"
|
||||
" bne %0, %z3, 2f \n"
|
||||
" .set mips0 \n"
|
||||
" move $1, %z4 \n"
|
||||
" .set mips3 \n"
|
||||
" sc $1, %1 \n"
|
||||
" beqzl $1, 1b \n"
|
||||
"2: \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (retval), "=R" (*m)
|
||||
: "R" (*m), "Jr" (old), "Jr" (new)
|
||||
: "memory");
|
||||
} else if (cpu_has_llsc) {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set noat \n"
|
||||
" .set mips3 \n"
|
||||
"1: ll %0, %2 # __cmpxchg_u32 \n"
|
||||
" bne %0, %z3, 2f \n"
|
||||
" .set mips0 \n"
|
||||
" move $1, %z4 \n"
|
||||
" .set mips3 \n"
|
||||
" sc $1, %1 \n"
|
||||
" beqz $1, 1b \n"
|
||||
"2: \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (retval), "=R" (*m)
|
||||
: "R" (*m), "Jr" (old), "Jr" (new)
|
||||
: "memory");
|
||||
} else {
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
if (retval == old)
|
||||
*m = new;
|
||||
local_irq_restore(flags); /* implies memory barrier */
|
||||
}
|
||||
#endif
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
if (retval == old)
|
||||
*m = new;
|
||||
local_irq_restore(flags); /* implies memory barrier */
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
|
||||
unsigned long new)
|
||||
{
|
||||
__u64 retval;
|
||||
#ifdef JIANGZHU_DEV
|
||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set noat \n"
|
||||
" .set mips3 \n"
|
||||
"1: lld %0, %2 # __cmpxchg_u64 \n"
|
||||
" bne %0, %z3, 2f \n"
|
||||
" move $1, %z4 \n"
|
||||
" scd $1, %1 \n"
|
||||
" beqzl $1, 1b \n"
|
||||
"2: \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (retval), "=R" (*m)
|
||||
: "R" (*m), "Jr" (old), "Jr" (new)
|
||||
: "memory");
|
||||
} else if (cpu_has_llsc) {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set noat \n"
|
||||
" .set mips3 \n"
|
||||
"1: lld %0, %2 # __cmpxchg_u64 \n"
|
||||
" bne %0, %z3, 2f \n"
|
||||
" move $1, %z4 \n"
|
||||
" scd $1, %1 \n"
|
||||
" beqz $1, 3f \n"
|
||||
"2: \n"
|
||||
" .subsection 2 \n"
|
||||
"3: b 1b \n"
|
||||
" .previous \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (retval), "=R" (*m)
|
||||
: "R" (*m), "Jr" (old), "Jr" (new)
|
||||
: "memory");
|
||||
} else {
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
if (retval == old)
|
||||
*m = new;
|
||||
local_irq_restore(flags); /* implies memory barrier */
|
||||
}
|
||||
#endif
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
if (retval == old)
|
||||
*m = new;
|
||||
local_irq_restore(flags); /* implies memory barrier */
|
||||
|
||||
/* smp_llsc_mb();*/
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline unsigned long __cmpxchg_u64_local(volatile int * m,
|
||||
unsigned long old, unsigned long new)
|
||||
{
|
||||
__u64 retval;
|
||||
|
||||
#ifdef JIANGZHU_DEV
|
||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set noat \n"
|
||||
" .set mips3 \n"
|
||||
"1: lld %0, %2 # __cmpxchg_u64 \n"
|
||||
" bne %0, %z3, 2f \n"
|
||||
" move $1, %z4 \n"
|
||||
" scd $1, %1 \n"
|
||||
" beqzl $1, 1b \n"
|
||||
"2: \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (retval), "=R" (*m)
|
||||
: "R" (*m), "Jr" (old), "Jr" (new)
|
||||
: "memory");
|
||||
} else if (cpu_has_llsc) {
|
||||
__asm__ __volatile__(
|
||||
" .set push \n"
|
||||
" .set noat \n"
|
||||
" .set mips3 \n"
|
||||
"1: lld %0, %2 # __cmpxchg_u64 \n"
|
||||
" bne %0, %z3, 2f \n"
|
||||
" move $1, %z4 \n"
|
||||
" scd $1, %1 \n"
|
||||
" beqz $1, 1b \n"
|
||||
"2: \n"
|
||||
" .set pop \n"
|
||||
: "=&r" (retval), "=R" (*m)
|
||||
: "R" (*m), "Jr" (old), "Jr" (new)
|
||||
: "memory");
|
||||
} else {
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
if (retval == old)
|
||||
*m = new;
|
||||
local_irq_restore(flags); /* implies memory barrier */
|
||||
}
|
||||
#endif
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
retval = *m;
|
||||
if (retval == old)
|
||||
*m = new;
|
||||
local_irq_restore(flags); /* implies memory barrier */
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#else
|
||||
extern unsigned long __cmpxchg_u64_unsupported_on_32bit_kernels(
|
||||
volatile int * m, unsigned long old, unsigned long new);
|
||||
#define __cmpxchg_u64 __cmpxchg_u64_unsupported_on_32bit_kernels
|
||||
extern unsigned long __cmpxchg_u64_local_unsupported_on_32bit_kernels(
|
||||
volatile int * m, unsigned long old, unsigned long new);
|
||||
#define __cmpxchg_u64_local __cmpxchg_u64_local_unsupported_on_32bit_kernels
|
||||
#endif
|
||||
|
||||
/* This function doesn't exist, so you'll get a linker error
|
||||
if something tries to do an invalid cmpxchg(). */
|
||||
extern void __cmpxchg_called_with_bad_pointer(void);
|
||||
|
||||
static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
|
||||
unsigned long new, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
return __cmpxchg_u32(ptr, old, new);
|
||||
case 8:
|
||||
return __cmpxchg_u64(ptr, old, new);
|
||||
}
|
||||
__cmpxchg_called_with_bad_pointer();
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline unsigned long __cmpxchg_local(volatile void * ptr,
|
||||
unsigned long old, unsigned long new, int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
return __cmpxchg_u32_local(ptr, old, new);
|
||||
case 8:
|
||||
return __cmpxchg_u64_local(ptr, old, new);
|
||||
}
|
||||
__cmpxchg_called_with_bad_pointer();
|
||||
return old;
|
||||
}
|
||||
|
||||
#define cmpxchg(ptr,old,new) \
|
||||
((__typeof__(*(ptr)))__cmpxchg((ptr), \
|
||||
(unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
|
||||
|
||||
#define cmpxchg_local(ptr,old,new) \
|
||||
((__typeof__(*(ptr)))__cmpxchg_local((ptr), \
|
||||
(unsigned long)(old), (unsigned long)(new),sizeof(*(ptr))))
|
||||
|
||||
#endif /* asm/system.h */
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef _ASM_GENERIC_BUG_H
|
||||
#define _ASM_GENERIC_BUG_H
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#define WARN_ON_ONCE(condition) ({ \
|
||||
static int __warned; \
|
||||
int __ret_warn_once = !!(condition); \
|
||||
\
|
||||
if (unlikely(__ret_warn_once) && !__warned) { \
|
||||
WARN_ON(1); \
|
||||
__warned = 1; \
|
||||
} \
|
||||
unlikely(__ret_warn_once); \
|
||||
})
|
||||
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef __ASM_SYSTEM_WRAPPER_H
|
||||
#define __ASM_SYSTEM_WRAPPER_H 1
|
||||
|
||||
#include_next <asm/system.h>
|
||||
|
||||
#ifdef CONFIG_ALPHA
|
||||
#define read_barrier_depends __asm__ __volatile__("mb": : :"memory")
|
||||
#else
|
||||
#define read_barrier_depends() do { } while(0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define smp_read_barrier_depends() read_barrier_depends()
|
||||
#else
|
||||
#define smp_read_barrier_depends() do { } while(0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef __LINUX_COMPILER_WRAPPER_H
|
||||
#define __LINUX_COMPILER_WRAPPER_H
|
||||
|
||||
#include_next <linux/compiler.h>
|
||||
|
||||
# define __force
|
||||
|
||||
#endif
|
||||
@@ -1,75 +0,0 @@
|
||||
#ifndef __LINUX_DELAY_WRAPPER_H
|
||||
#define __LINUX_DELAY_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/delay.h>
|
||||
|
||||
#include <linux/version.h>
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,29)
|
||||
#include <linux/time.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/param.h>
|
||||
/*
|
||||
* We define MAX_MSEC_OFFSET as the maximal value that can be accepted by
|
||||
* msecs_to_jiffies() without risking a multiply overflow. This function
|
||||
* returns MAX_JIFFY_OFFSET for arguments above those values.
|
||||
*/
|
||||
|
||||
#if HZ <= 1000 && !(1000 % HZ)
|
||||
# define MAX_MSEC_OFFSET \
|
||||
(ULONG_MAX - (1000 / HZ) + 1)
|
||||
#elif HZ > 1000 && !(HZ % 1000)
|
||||
# define MAX_MSEC_OFFSET \
|
||||
(ULONG_MAX / (HZ / 1000))
|
||||
#else
|
||||
# define MAX_MSEC_OFFSET \
|
||||
((ULONG_MAX - 999) / HZ)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert jiffies to milliseconds and back.
|
||||
*
|
||||
* Avoid unnecessary multiplications/divisions in the
|
||||
* two most common HZ cases:
|
||||
*/
|
||||
static inline unsigned int jiffies_to_msecs(const unsigned long j)
|
||||
{
|
||||
#if HZ <= 1000 && !(1000 % HZ)
|
||||
return (1000 / HZ) * j;
|
||||
#elif HZ > 1000 && !(HZ % 1000)
|
||||
return (j + (HZ / 1000) - 1)/(HZ / 1000);
|
||||
#else
|
||||
return (j * 1000) / HZ;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned long msecs_to_jiffies(const unsigned int m)
|
||||
{
|
||||
if (MAX_MSEC_OFFSET < UINT_MAX && m > (unsigned int)MAX_MSEC_OFFSET)
|
||||
return MAX_JIFFY_OFFSET;
|
||||
#if HZ <= 1000 && !(1000 % HZ)
|
||||
return ((unsigned long)m + (1000 / HZ) - 1) / (1000 / HZ);
|
||||
#elif HZ > 1000 && !(HZ % 1000)
|
||||
return (unsigned long)m * (HZ / 1000);
|
||||
#else
|
||||
return ((unsigned long)m * HZ + 999) / 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* linux kernel < 2.4.29 */
|
||||
|
||||
/**
|
||||
* msleep_interruptible - sleep waiting for waitqueue interruptions
|
||||
* @msecs: Time in milliseconds to sleep for
|
||||
*/
|
||||
static inline unsigned long msleep_interruptible(unsigned int msecs)
|
||||
{
|
||||
unsigned long timeout = msecs_to_jiffies(msecs);
|
||||
|
||||
while (timeout && !signal_pending(current)) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
timeout = schedule_timeout(timeout);
|
||||
}
|
||||
return jiffies_to_msecs(timeout);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,34 +0,0 @@
|
||||
#ifndef __LINUX_DMI_WRAPPER_H
|
||||
#define __LINUX_DMI_WRAPPER_H 1
|
||||
|
||||
enum dmi_field {
|
||||
DMI_NONE,
|
||||
DMI_BIOS_VENDOR,
|
||||
DMI_BIOS_VERSION,
|
||||
DMI_BIOS_DATE,
|
||||
DMI_SYS_VENDOR,
|
||||
DMI_PRODUCT_NAME,
|
||||
DMI_PRODUCT_VERSION,
|
||||
DMI_PRODUCT_SERIAL,
|
||||
DMI_PRODUCT_UUID,
|
||||
DMI_BOARD_VENDOR,
|
||||
DMI_BOARD_NAME,
|
||||
DMI_BOARD_VERSION,
|
||||
DMI_BOARD_SERIAL,
|
||||
DMI_BOARD_ASSET_TAG,
|
||||
DMI_CHASSIS_VENDOR,
|
||||
DMI_CHASSIS_TYPE,
|
||||
DMI_CHASSIS_VERSION,
|
||||
DMI_CHASSIS_SERIAL,
|
||||
DMI_CHASSIS_ASSET_TAG,
|
||||
DMI_STRING_MAX
|
||||
};
|
||||
|
||||
/* 2.4 kernels didn't provide a general ability to query DMI. We'll just
|
||||
* always return NULL, since this functionality isn't critical. */
|
||||
static inline
|
||||
const char *dmi_get_system_info(int field) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,71 +0,0 @@
|
||||
#ifndef __LINUX_ETHERDEVICE_WRAPPER_H
|
||||
#define __LINUX_ETHERDEVICE_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/etherdevice.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
/**
|
||||
* is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
|
||||
* @addr: Pointer to a six-byte array containing the Ethernet address
|
||||
*
|
||||
* Return true if the address is a multicast address.
|
||||
* By definition the broadcast address is also a multicast address.
|
||||
*/
|
||||
static inline int is_multicast_ether_addr(const u8 *addr)
|
||||
{
|
||||
return (0x01 & addr[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* is_local_ether_addr - Determine if the Ethernet address is locally-assigned
|
||||
* one (IEEE 802).
|
||||
* @addr: Pointer to a six-byte array containing the Ethernet address
|
||||
*
|
||||
* Return true if the address is a local address.
|
||||
*/
|
||||
static inline int is_local_ether_addr(const u8 *addr)
|
||||
{
|
||||
return (0x02 & addr[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* is_broadcast_ether_addr - Determine if the Ethernet address is broadcast
|
||||
* @addr: Pointer to a six-byte array containing the Ethernet address
|
||||
*
|
||||
* Return true if the address is the broadcast address.
|
||||
*/
|
||||
static inline int is_broadcast_ether_addr(const u8 *addr)
|
||||
{
|
||||
return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* random_ether_addr - Generate software assigned random Ethernet address
|
||||
* @addr: Pointer to a six-byte array containing the Ethernet address
|
||||
*
|
||||
* Generate a random Ethernet address (MAC) that is not multicast
|
||||
* and has the local assigned bit set.
|
||||
*/
|
||||
static inline void random_ether_addr(u8 *addr)
|
||||
{
|
||||
get_random_bytes (addr, ETH_ALEN);
|
||||
addr [0] &= 0xfe; /* clear multicast bit */
|
||||
addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
|
||||
}
|
||||
|
||||
/**
|
||||
* compare_ether_addr - Compare two Ethernet addresses
|
||||
* @addr1: Pointer to a six-byte array containing the Ethernet address
|
||||
* @addr2: Pointer other six-byte array containing the Ethernet address
|
||||
*
|
||||
* Compare two ethernet addresses, returns 0 if equal
|
||||
*/
|
||||
static inline unsigned compare_ether_addr(const u8 *addr1, const u8 *addr2)
|
||||
{
|
||||
const u16 *a = (const u16 *) addr1;
|
||||
const u16 *b = (const u16 *) addr2;
|
||||
|
||||
return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,82 +0,0 @@
|
||||
#ifndef __LINUX_GENERIC_NETLINK_H
|
||||
#define __LINUX_GENERIC_NETLINK_H
|
||||
|
||||
#include <linux/netlink.h>
|
||||
|
||||
#define GENL_NAMSIZ 16 /* length of family name */
|
||||
|
||||
#define GENL_MIN_ID NLMSG_MIN_TYPE
|
||||
#define GENL_MAX_ID 1023
|
||||
|
||||
struct genlmsghdr {
|
||||
__u8 cmd;
|
||||
__u8 version;
|
||||
__u16 reserved;
|
||||
};
|
||||
|
||||
#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
|
||||
|
||||
#define GENL_ADMIN_PERM 0x01
|
||||
#define GENL_CMD_CAP_DO 0x02
|
||||
#define GENL_CMD_CAP_DUMP 0x04
|
||||
#define GENL_CMD_CAP_HASPOL 0x08
|
||||
|
||||
/*
|
||||
* List of reserved static generic netlink identifiers:
|
||||
*/
|
||||
#define GENL_ID_GENERATE 0
|
||||
#define GENL_ID_CTRL NLMSG_MIN_TYPE
|
||||
|
||||
/**************************************************************************
|
||||
* Controller
|
||||
**************************************************************************/
|
||||
|
||||
enum {
|
||||
CTRL_CMD_UNSPEC,
|
||||
CTRL_CMD_NEWFAMILY,
|
||||
CTRL_CMD_DELFAMILY,
|
||||
CTRL_CMD_GETFAMILY,
|
||||
CTRL_CMD_NEWOPS,
|
||||
CTRL_CMD_DELOPS,
|
||||
CTRL_CMD_GETOPS,
|
||||
CTRL_CMD_NEWMCAST_GRP,
|
||||
CTRL_CMD_DELMCAST_GRP,
|
||||
CTRL_CMD_GETMCAST_GRP, /* unused */
|
||||
__CTRL_CMD_MAX,
|
||||
};
|
||||
|
||||
#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
|
||||
|
||||
enum {
|
||||
CTRL_ATTR_UNSPEC,
|
||||
CTRL_ATTR_FAMILY_ID,
|
||||
CTRL_ATTR_FAMILY_NAME,
|
||||
CTRL_ATTR_VERSION,
|
||||
CTRL_ATTR_HDRSIZE,
|
||||
CTRL_ATTR_MAXATTR,
|
||||
CTRL_ATTR_OPS,
|
||||
CTRL_ATTR_MCAST_GROUPS,
|
||||
__CTRL_ATTR_MAX,
|
||||
};
|
||||
|
||||
#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
|
||||
|
||||
enum {
|
||||
CTRL_ATTR_OP_UNSPEC,
|
||||
CTRL_ATTR_OP_ID,
|
||||
CTRL_ATTR_OP_FLAGS,
|
||||
__CTRL_ATTR_OP_MAX,
|
||||
};
|
||||
|
||||
#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1)
|
||||
|
||||
enum {
|
||||
CTRL_ATTR_MCAST_GRP_UNSPEC,
|
||||
CTRL_ATTR_MCAST_GRP_NAME,
|
||||
CTRL_ATTR_MCAST_GRP_ID,
|
||||
__CTRL_ATTR_MCAST_GRP_MAX,
|
||||
};
|
||||
|
||||
#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
|
||||
|
||||
#endif /* __LINUX_GENERIC_NETLINK_H */
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef __LINUX_GFP_WRAPPER_H
|
||||
#define __LINUX_GFP_WRAPPER_H 1
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
#endif /* linux/gfp.h */
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef __LINUX_ICMP_WRAPPER_H
|
||||
#define __LINUX_ICMP_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/icmp.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
static inline struct icmphdr *icmp_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct icmphdr *)skb_transport_header(skb);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef __LINUX_IF_ETHER_WRAPPER_H
|
||||
#define __LINUX_IF_ETHER_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/if_ether.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct ethhdr *)skb_mac_header(skb);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,71 +0,0 @@
|
||||
#ifndef __LINUX_IF_VLAN_WRAPPER_H
|
||||
#define __LINUX_IF_VLAN_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/if_vlan.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct vlan_ethhdr *)skb_mac_header(skb);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,26)
|
||||
static inline struct sk_buff *vlan_put_tag(struct sk_buff *skb, unsigned short tag)
|
||||
{
|
||||
struct vlan_ethhdr *veth;
|
||||
|
||||
if (skb_headroom(skb) < VLAN_HLEN) {
|
||||
struct sk_buff *sk_tmp = skb;
|
||||
skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN);
|
||||
kfree_skb(sk_tmp);
|
||||
if (!skb) {
|
||||
printk(KERN_ERR "vlan: failed to realloc headroom\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
skb = skb_unshare(skb, GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
printk(KERN_ERR "vlan: failed to unshare skbuff\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
|
||||
|
||||
/* Move the mac addresses to the beginning of the new header. */
|
||||
memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
|
||||
|
||||
/* first, the ethernet type */
|
||||
veth->h_vlan_proto = htons(ETH_P_8021Q);
|
||||
|
||||
/* now, the tag */
|
||||
veth->h_vlan_TCI = htons(tag);
|
||||
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define vlan_put_tag(x,y) fix_vlan_put_tag((x),(y));
|
||||
|
||||
/* For some reason, older versions of vlan_put_tag do not adjust the
|
||||
* pointer to the beginning of the MAC header. We get around that by
|
||||
* this hack. Ugh. */
|
||||
static inline struct sk_buff *fix_vlan_put_tag(struct sk_buff *skb, unsigned short tag)
|
||||
{
|
||||
skb = (vlan_put_tag)(skb, tag);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
return skb;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef __LINUX_IP_WRAPPER_H
|
||||
#define __LINUX_IP_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/ip.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct iphdr *)skb_network_header(skb);
|
||||
}
|
||||
|
||||
static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
|
||||
{
|
||||
return ip_hdr(skb)->ihl * 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef __LINUX_IPV6_WRAPPER_H
|
||||
#define __LINUX_IPV6_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/ipv6.h>
|
||||
|
||||
static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct ipv6hdr *)skb_network_header(skb);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,30 +0,0 @@
|
||||
#ifndef __LINUX_JIFFIES_WRAPPER_H
|
||||
#define __LINUX_JIFFIES_WRAPPER_H 1
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
extern unsigned long volatile jiffies;
|
||||
|
||||
/* 'jiffies_64' are not supported in 2.4 kernels. Here we fake
|
||||
* compatibility by always just returning the plain 'jiffies' value.
|
||||
* This means jiffies will wrap every 49 days. */
|
||||
#define get_jiffies_64(void) ((u64)jiffies)
|
||||
|
||||
/* Same as above, but does so with platform independent 64bit types.
|
||||
* These must be used when utilizing jiffies_64 (i.e. return value of
|
||||
* get_jiffies_64() */
|
||||
#define time_after64(a,b) \
|
||||
(typecheck(__u64, a) && \
|
||||
typecheck(__u64, b) && \
|
||||
((__s64)(b) - (__s64)(a) < 0))
|
||||
#define time_before64(a,b) time_after64(b,a)
|
||||
|
||||
#define time_after_eq64(a,b) \
|
||||
(typecheck(__u64, a) && \
|
||||
typecheck(__u64, b) && \
|
||||
((__s64)(a) - (__s64)(b) >= 0))
|
||||
#define time_before_eq64(a,b) time_after_eq64(b,a)
|
||||
|
||||
#endif
|
||||
@@ -1,67 +0,0 @@
|
||||
#ifndef __LINUX_KERNEL_WRAPPER_H
|
||||
#define __LINUX_KERNEL_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/kernel.h>
|
||||
#include <linux/config.h>
|
||||
#include <asm/bug.h>
|
||||
|
||||
/**
|
||||
* container_of - cast a member of a structure out to the containing structure
|
||||
* @ptr: the pointer to the member.
|
||||
* @type: the type of the container struct this is embedded in.
|
||||
* @member: the name of the member within the struct.
|
||||
*
|
||||
*/
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
|
||||
/*
|
||||
* Check at compile time that something is of a particular type.
|
||||
* Always evaluates to 1 so you may use it easily in comparisons.
|
||||
*/
|
||||
#define typecheck(type,x) \
|
||||
({ type __dummy; \
|
||||
typeof(x) __dummy2; \
|
||||
(void)(&__dummy == &__dummy2); \
|
||||
1; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Check at compile time that 'function' is a certain type, or is a pointer
|
||||
* to that type (needs to use typedef for the function type.)
|
||||
*/
|
||||
#define typecheck_fn(type,function) \
|
||||
({ typeof(type) __tmp = function; \
|
||||
(void)__tmp; \
|
||||
})
|
||||
|
||||
int vprintk(const char *msg, ...)
|
||||
__attribute__((format(printf, 1, 0)));
|
||||
|
||||
/* Force a compilation error if condition is true */
|
||||
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
|
||||
|
||||
/**
|
||||
* might_sleep - annotation for functions that can sleep
|
||||
*
|
||||
* this macro will print a stack trace if it is executed in an atomic
|
||||
* context (spinlock, irq-handler, ...).
|
||||
*
|
||||
* This is a useful debugging help to be able to catch problems early and not
|
||||
* be bitten later when the calling function happens to sleep when it is not
|
||||
* supposed to.
|
||||
*/
|
||||
#define might_resched() do { } while (0)
|
||||
|
||||
#ifdef CONFIG_DEBUG_SPINLOCK
|
||||
void __might_sleep(char *file, int line);
|
||||
# define might_sleep() \
|
||||
do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0)
|
||||
#else
|
||||
# define might_sleep() do { might_resched(); } while (0)
|
||||
#endif
|
||||
|
||||
#define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0)
|
||||
|
||||
#endif
|
||||
@@ -1,34 +0,0 @@
|
||||
#ifndef _LINUX_KTHREAD_H
|
||||
#define _LINUX_KTHREAD_H
|
||||
/* Simple interface for creating and stopping kernel threads without mess. */
|
||||
#include <linux/sched.h>
|
||||
|
||||
struct task_struct *kthread_create(int (*threadfn)(void *data),
|
||||
void *data,
|
||||
const char namefmt[], ...);
|
||||
|
||||
/**
|
||||
* kthread_run - create and wake a thread.
|
||||
* @threadfn: the function to run until signal_pending(current).
|
||||
* @data: data ptr for @threadfn.
|
||||
* @namefmt: printf-style name for the thread.
|
||||
*
|
||||
* Description: Convenient wrapper for kthread_create() followed by
|
||||
* wake_up_process(). Returns the kthread or ERR_PTR(-ENOMEM).
|
||||
*/
|
||||
#define kthread_run(threadfn, data, namefmt, ...) \
|
||||
({ \
|
||||
struct task_struct *__k \
|
||||
= kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \
|
||||
if (!IS_ERR(__k)) \
|
||||
wake_up_process(__k); \
|
||||
__k; \
|
||||
})
|
||||
|
||||
int kthread_stop(struct task_struct *k);
|
||||
int kthread_should_stop(void);
|
||||
|
||||
int kthreadd(void *unused);
|
||||
extern struct task_struct *kthreadd_task;
|
||||
|
||||
#endif /* _LINUX_KTHREAD_H */
|
||||
@@ -1,493 +0,0 @@
|
||||
#ifndef __LINUX_LIST_WRAPPER_H
|
||||
#define __LINUX_LIST_WRAPPER_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include_next <linux/list.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#define LIST_POISON1 ((void *) 0x00100100)
|
||||
#define LIST_POISON2 ((void *) 0x00200200)
|
||||
|
||||
/*
|
||||
* Insert a new entry between two known consecutive entries.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static inline void __list_add_rcu(struct list_head * new,
|
||||
struct list_head * prev, struct list_head * next)
|
||||
{
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
smp_wmb();
|
||||
next->prev = new;
|
||||
prev->next = new;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_add_rcu - add a new entry to rcu-protected list
|
||||
* @new: new entry to be added
|
||||
* @head: list head to add it after
|
||||
*
|
||||
* Insert a new entry after the specified head.
|
||||
* This is good for implementing stacks.
|
||||
*
|
||||
* The caller must take whatever precautions are necessary
|
||||
* (such as holding appropriate locks) to avoid racing
|
||||
* with another list-mutation primitive, such as list_add_rcu()
|
||||
* or list_del_rcu(), running on this same list.
|
||||
* However, it is perfectly legal to run concurrently with
|
||||
* the _rcu list-traversal primitives, such as
|
||||
* list_for_each_entry_rcu().
|
||||
*/
|
||||
static inline void list_add_rcu(struct list_head *new, struct list_head *head)
|
||||
{
|
||||
__list_add_rcu(new, head, head->next);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_add_tail_rcu - add a new entry to rcu-protected list
|
||||
* @new: new entry to be added
|
||||
* @head: list head to add it before
|
||||
*
|
||||
* Insert a new entry before the specified head.
|
||||
* This is useful for implementing queues.
|
||||
*
|
||||
* The caller must take whatever precautions are necessary
|
||||
* (such as holding appropriate locks) to avoid racing
|
||||
* with another list-mutation primitive, such as list_add_tail_rcu()
|
||||
* or list_del_rcu(), running on this same list.
|
||||
* However, it is perfectly legal to run concurrently with
|
||||
* the _rcu list-traversal primitives, such as
|
||||
* list_for_each_entry_rcu().
|
||||
*/
|
||||
static inline void list_add_tail_rcu(struct list_head *new,
|
||||
struct list_head *head)
|
||||
{
|
||||
__list_add_rcu(new, head->prev, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del_rcu - deletes entry from list without re-initialization
|
||||
* @entry: the element to delete from the list.
|
||||
*
|
||||
* Note: list_empty() on entry does not return true after this,
|
||||
* the entry is in an undefined state. It is useful for RCU based
|
||||
* lockfree traversal.
|
||||
*
|
||||
* In particular, it means that we can not poison the forward
|
||||
* pointers that may still be used for walking the list.
|
||||
*
|
||||
* The caller must take whatever precautions are necessary
|
||||
* (such as holding appropriate locks) to avoid racing
|
||||
* with another list-mutation primitive, such as list_del_rcu()
|
||||
* or list_add_rcu(), running on this same list.
|
||||
* However, it is perfectly legal to run concurrently with
|
||||
* the _rcu list-traversal primitives, such as
|
||||
* list_for_each_entry_rcu().
|
||||
*
|
||||
* Note that the caller is not permitted to immediately free
|
||||
* the newly deleted entry. Instead, either synchronize_rcu()
|
||||
* or call_rcu() must be used to defer freeing until an RCU
|
||||
* grace period has elapsed.
|
||||
*/
|
||||
static inline void list_del_rcu(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
entry->prev = LIST_POISON2;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_replace_rcu - replace old entry by new one
|
||||
* @old : the element to be replaced
|
||||
* @new : the new element to insert
|
||||
*
|
||||
* The @old entry will be replaced with the @new entry atomically.
|
||||
* Note: @old should not be empty.
|
||||
*/
|
||||
static inline void list_replace_rcu(struct list_head *old,
|
||||
struct list_head *new)
|
||||
{
|
||||
new->next = old->next;
|
||||
new->prev = old->prev;
|
||||
smp_wmb();
|
||||
new->next->prev = new;
|
||||
new->prev->next = new;
|
||||
old->prev = LIST_POISON2;
|
||||
}
|
||||
/**
|
||||
* list_for_each_rcu - iterate over an rcu-protected list
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
*
|
||||
* This list-traversal primitive may safely run concurrently with
|
||||
* the _rcu list-mutation primitives such as list_add_rcu()
|
||||
* as long as the traversal is guarded by rcu_read_lock().
|
||||
*/
|
||||
#define list_for_each_rcu(pos, head) \
|
||||
for (pos = (head)->next; \
|
||||
prefetch(rcu_dereference(pos)->next), pos != (head); \
|
||||
pos = pos->next)
|
||||
|
||||
#define __list_for_each_rcu(pos, head) \
|
||||
for (pos = (head)->next; \
|
||||
rcu_dereference(pos) != (head); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* list_for_each_entry_rcu - iterate over rcu list of given type
|
||||
* @pos: the type * to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*
|
||||
* This list-traversal primitive may safely run concurrently with
|
||||
* the _rcu list-mutation primitives such as list_add_rcu()
|
||||
* as long as the traversal is guarded by rcu_read_lock().
|
||||
*/
|
||||
#define list_for_each_entry_rcu(pos, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
||||
prefetch(rcu_dereference(pos)->member.next), \
|
||||
&pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
|
||||
|
||||
/**
|
||||
* list_for_each_continue_rcu
|
||||
* @pos: the &struct list_head to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
*
|
||||
* Iterate over an rcu-protected list, continuing after current point.
|
||||
*
|
||||
* This list-traversal primitive may safely run concurrently with
|
||||
* the _rcu list-mutation primitives such as list_add_rcu()
|
||||
* as long as the traversal is guarded by rcu_read_lock().
|
||||
*/
|
||||
#define list_for_each_continue_rcu(pos, head) \
|
||||
for ((pos) = (pos)->next; \
|
||||
prefetch(rcu_dereference((pos))->next), (pos) != (head); \
|
||||
(pos) = (pos)->next)
|
||||
|
||||
/*
|
||||
* Double linked lists with a single pointer list head.
|
||||
* Mostly useful for hash tables where the two pointer list head is
|
||||
* too wasteful.
|
||||
* You lose the ability to access the tail in O(1).
|
||||
*/
|
||||
|
||||
struct hlist_head {
|
||||
struct hlist_node *first;
|
||||
};
|
||||
|
||||
struct hlist_node {
|
||||
struct hlist_node *next, **pprev;
|
||||
};
|
||||
|
||||
#define HLIST_HEAD_INIT { .first = NULL }
|
||||
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
|
||||
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
|
||||
static inline void INIT_HLIST_NODE(struct hlist_node *h)
|
||||
{
|
||||
h->next = NULL;
|
||||
h->pprev = NULL;
|
||||
}
|
||||
|
||||
static inline int hlist_unhashed(const struct hlist_node *h)
|
||||
{
|
||||
return !h->pprev;
|
||||
}
|
||||
|
||||
static inline int hlist_empty(const struct hlist_head *h)
|
||||
{
|
||||
return !h->first;
|
||||
}
|
||||
|
||||
static inline void __hlist_del(struct hlist_node *n)
|
||||
{
|
||||
struct hlist_node *next = n->next;
|
||||
struct hlist_node **pprev = n->pprev;
|
||||
*pprev = next;
|
||||
if (next)
|
||||
next->pprev = pprev;
|
||||
}
|
||||
|
||||
static inline void hlist_del(struct hlist_node *n)
|
||||
{
|
||||
__hlist_del(n);
|
||||
n->next = LIST_POISON1;
|
||||
n->pprev = LIST_POISON2;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_del_rcu - deletes entry from hash list without re-initialization
|
||||
* @n: the element to delete from the hash list.
|
||||
*
|
||||
* Note: list_unhashed() on entry does not return true after this,
|
||||
* the entry is in an undefined state. It is useful for RCU based
|
||||
* lockfree traversal.
|
||||
*
|
||||
* In particular, it means that we can not poison the forward
|
||||
* pointers that may still be used for walking the hash list.
|
||||
*
|
||||
* The caller must take whatever precautions are necessary
|
||||
* (such as holding appropriate locks) to avoid racing
|
||||
* with another list-mutation primitive, such as hlist_add_head_rcu()
|
||||
* or hlist_del_rcu(), running on this same list.
|
||||
* However, it is perfectly legal to run concurrently with
|
||||
* the _rcu list-traversal primitives, such as
|
||||
* hlist_for_each_entry().
|
||||
*/
|
||||
static inline void hlist_del_rcu(struct hlist_node *n)
|
||||
{
|
||||
__hlist_del(n);
|
||||
n->pprev = LIST_POISON2;
|
||||
}
|
||||
|
||||
static inline void hlist_del_init(struct hlist_node *n)
|
||||
{
|
||||
if (!hlist_unhashed(n)) {
|
||||
__hlist_del(n);
|
||||
INIT_HLIST_NODE(n);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_replace_rcu - replace old entry by new one
|
||||
* @old : the element to be replaced
|
||||
* @new : the new element to insert
|
||||
*
|
||||
* The @old entry will be replaced with the @new entry atomically.
|
||||
*/
|
||||
static inline void hlist_replace_rcu(struct hlist_node *old,
|
||||
struct hlist_node *new)
|
||||
{
|
||||
struct hlist_node *next = old->next;
|
||||
|
||||
new->next = next;
|
||||
new->pprev = old->pprev;
|
||||
smp_wmb();
|
||||
if (next)
|
||||
new->next->pprev = &new->next;
|
||||
*new->pprev = new;
|
||||
old->pprev = LIST_POISON2;
|
||||
}
|
||||
|
||||
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
||||
{
|
||||
struct hlist_node *first = h->first;
|
||||
n->next = first;
|
||||
if (first)
|
||||
first->pprev = &n->next;
|
||||
h->first = n;
|
||||
n->pprev = &h->first;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hlist_add_head_rcu
|
||||
* @n: the element to add to the hash list.
|
||||
* @h: the list to add to.
|
||||
*
|
||||
* Description:
|
||||
* Adds the specified element to the specified hlist,
|
||||
* while permitting racing traversals.
|
||||
*
|
||||
* The caller must take whatever precautions are necessary
|
||||
* (such as holding appropriate locks) to avoid racing
|
||||
* with another list-mutation primitive, such as hlist_add_head_rcu()
|
||||
* or hlist_del_rcu(), running on this same list.
|
||||
* However, it is perfectly legal to run concurrently with
|
||||
* the _rcu list-traversal primitives, such as
|
||||
* hlist_for_each_entry_rcu(), used to prevent memory-consistency
|
||||
* problems on Alpha CPUs. Regardless of the type of CPU, the
|
||||
* list-traversal primitive must be guarded by rcu_read_lock().
|
||||
*/
|
||||
static inline void hlist_add_head_rcu(struct hlist_node *n,
|
||||
struct hlist_head *h)
|
||||
{
|
||||
struct hlist_node *first = h->first;
|
||||
n->next = first;
|
||||
n->pprev = &h->first;
|
||||
smp_wmb();
|
||||
if (first)
|
||||
first->pprev = &n->next;
|
||||
h->first = n;
|
||||
}
|
||||
|
||||
/* next must be != NULL */
|
||||
static inline void hlist_add_before(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
n->pprev = next->pprev;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
*(n->pprev) = n;
|
||||
}
|
||||
|
||||
static inline void hlist_add_after(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
next->next = n->next;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
|
||||
if(next->next)
|
||||
next->next->pprev = &next->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_add_before_rcu
|
||||
* @n: the new element to add to the hash list.
|
||||
* @next: the existing element to add the new element before.
|
||||
*
|
||||
* Description:
|
||||
* Adds the specified element to the specified hlist
|
||||
* before the specified node while permitting racing traversals.
|
||||
*
|
||||
* The caller must take whatever precautions are necessary
|
||||
* (such as holding appropriate locks) to avoid racing
|
||||
* with another list-mutation primitive, such as hlist_add_head_rcu()
|
||||
* or hlist_del_rcu(), running on this same list.
|
||||
* However, it is perfectly legal to run concurrently with
|
||||
* the _rcu list-traversal primitives, such as
|
||||
* hlist_for_each_entry_rcu(), used to prevent memory-consistency
|
||||
* problems on Alpha CPUs.
|
||||
*/
|
||||
static inline void hlist_add_before_rcu(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
n->pprev = next->pprev;
|
||||
n->next = next;
|
||||
smp_wmb();
|
||||
next->pprev = &n->next;
|
||||
*(n->pprev) = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_add_after_rcu
|
||||
* @prev: the existing element to add the new element after.
|
||||
* @n: the new element to add to the hash list.
|
||||
*
|
||||
* Description:
|
||||
* Adds the specified element to the specified hlist
|
||||
* after the specified node while permitting racing traversals.
|
||||
*
|
||||
* The caller must take whatever precautions are necessary
|
||||
* (such as holding appropriate locks) to avoid racing
|
||||
* with another list-mutation primitive, such as hlist_add_head_rcu()
|
||||
* or hlist_del_rcu(), running on this same list.
|
||||
* However, it is perfectly legal to run concurrently with
|
||||
* the _rcu list-traversal primitives, such as
|
||||
* hlist_for_each_entry_rcu(), used to prevent memory-consistency
|
||||
* problems on Alpha CPUs.
|
||||
*/
|
||||
static inline void hlist_add_after_rcu(struct hlist_node *prev,
|
||||
struct hlist_node *n)
|
||||
{
|
||||
n->next = prev->next;
|
||||
n->pprev = &prev->next;
|
||||
smp_wmb();
|
||||
prev->next = n;
|
||||
if (n->next)
|
||||
n->next->pprev = &n->next;
|
||||
}
|
||||
|
||||
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
|
||||
|
||||
#define hlist_for_each(pos, head) \
|
||||
for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
|
||||
pos = pos->next)
|
||||
|
||||
#define hlist_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
|
||||
pos = n)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry - iterate over list of given type
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry(tpos, pos, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_continue - iterate over a hlist continuing after current point
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_continue(tpos, pos, member) \
|
||||
for (pos = (pos)->next; \
|
||||
pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_from - iterate over a hlist continuing from current point
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_from(tpos, pos, member) \
|
||||
for (; pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @n: another &struct hlist_node to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*/
|
||||
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ n = pos->next; 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = n)
|
||||
|
||||
/**
|
||||
* hlist_for_each_entry_rcu - iterate over rcu list of given type
|
||||
* @tpos: the type * to use as a loop cursor.
|
||||
* @pos: the &struct hlist_node to use as a loop cursor.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the hlist_node within the struct.
|
||||
*
|
||||
* This list-traversal primitive may safely run concurrently with
|
||||
* the _rcu list-mutation primitives such as hlist_add_head_rcu()
|
||||
* as long as the traversal is guarded by rcu_read_lock().
|
||||
*/
|
||||
#define hlist_for_each_entry_rcu(tpos, pos, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
rcu_dereference(pos) && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23)
|
||||
/**
|
||||
* list_for_each_entry_safe - iterate over list of given type safe against remov
|
||||
al of list entry
|
||||
* @pos: the type * to use as a loop counter.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
#endif /* linux kernel < 2.4.23 */
|
||||
|
||||
|
||||
#else
|
||||
#warning "don't include kernel headers in userspace"
|
||||
#endif /* __KERNEL__ */
|
||||
#endif
|
||||
@@ -1,80 +0,0 @@
|
||||
#ifndef __LINUX_LLC_H
|
||||
#define __LINUX_LLC_H
|
||||
/*
|
||||
* IEEE 802.2 User Interface SAPs for Linux, data structures and indicators.
|
||||
*
|
||||
* Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
|
||||
*
|
||||
* This program can be redistributed or modified under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation.
|
||||
* This program is distributed without any warranty or implied warranty
|
||||
* of merchantability or fitness for a particular purpose.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
#define __LLC_SOCK_SIZE__ 16 /* sizeof(sockaddr_llc), word align. */
|
||||
struct sockaddr_llc {
|
||||
sa_family_t sllc_family; /* AF_LLC */
|
||||
sa_family_t sllc_arphrd; /* ARPHRD_ETHER */
|
||||
unsigned char sllc_test;
|
||||
unsigned char sllc_xid;
|
||||
unsigned char sllc_ua; /* UA data, only for SOCK_STREAM. */
|
||||
unsigned char sllc_sap;
|
||||
unsigned char sllc_mac[IFHWADDRLEN];
|
||||
unsigned char __pad[__LLC_SOCK_SIZE__ - sizeof(sa_family_t) * 2 -
|
||||
sizeof(unsigned char) * 4 - IFHWADDRLEN];
|
||||
};
|
||||
|
||||
/* sockopt definitions. */
|
||||
enum llc_sockopts {
|
||||
LLC_OPT_UNKNOWN = 0,
|
||||
LLC_OPT_RETRY, /* max retrans attempts. */
|
||||
LLC_OPT_SIZE, /* max PDU size (octets). */
|
||||
LLC_OPT_ACK_TMR_EXP, /* ack expire time (secs). */
|
||||
LLC_OPT_P_TMR_EXP, /* pf cycle expire time (secs). */
|
||||
LLC_OPT_REJ_TMR_EXP, /* rej sent expire time (secs). */
|
||||
LLC_OPT_BUSY_TMR_EXP, /* busy state expire time (secs). */
|
||||
LLC_OPT_TX_WIN, /* tx window size. */
|
||||
LLC_OPT_RX_WIN, /* rx window size. */
|
||||
LLC_OPT_MAX
|
||||
};
|
||||
|
||||
#define LLC_OPT_MAX_RETRY 100
|
||||
#define LLC_OPT_MAX_SIZE 4196
|
||||
#define LLC_OPT_MAX_WIN 127
|
||||
#define LLC_OPT_MAX_ACK_TMR_EXP 60
|
||||
#define LLC_OPT_MAX_P_TMR_EXP 60
|
||||
#define LLC_OPT_MAX_REJ_TMR_EXP 60
|
||||
#define LLC_OPT_MAX_BUSY_TMR_EXP 60
|
||||
|
||||
/* LLC SAP types. */
|
||||
#define LLC_SAP_NULL 0x00 /* NULL SAP. */
|
||||
#define LLC_SAP_LLC 0x02 /* LLC Sublayer Managment. */
|
||||
#define LLC_SAP_SNA 0x04 /* SNA Path Control. */
|
||||
#define LLC_SAP_PNM 0x0E /* Proway Network Managment. */
|
||||
#define LLC_SAP_IP 0x06 /* TCP/IP. */
|
||||
#define LLC_SAP_BSPAN 0x42 /* Bridge Spanning Tree Proto */
|
||||
#define LLC_SAP_MMS 0x4E /* Manufacturing Message Srv. */
|
||||
#define LLC_SAP_8208 0x7E /* ISO 8208 */
|
||||
#define LLC_SAP_3COM 0x80 /* 3COM. */
|
||||
#define LLC_SAP_PRO 0x8E /* Proway Active Station List */
|
||||
#define LLC_SAP_SNAP 0xAA /* SNAP. */
|
||||
#define LLC_SAP_BANYAN 0xBC /* Banyan. */
|
||||
#define LLC_SAP_IPX 0xE0 /* IPX/SPX. */
|
||||
#define LLC_SAP_NETBEUI 0xF0 /* NetBEUI. */
|
||||
#define LLC_SAP_LANMGR 0xF4 /* LanManager. */
|
||||
#define LLC_SAP_IMPL 0xF8 /* IMPL */
|
||||
#define LLC_SAP_DISC 0xFC /* Discovery */
|
||||
#define LLC_SAP_OSI 0xFE /* OSI Network Layers. */
|
||||
#define LLC_SAP_LAR 0xDC /* LAN Address Resolution */
|
||||
#define LLC_SAP_RM 0xD4 /* Resource Management */
|
||||
#define LLC_SAP_GLOBAL 0xFF /* Global SAP. */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#define LLC_SAP_DYN_START 0xC0
|
||||
#define LLC_SAP_DYN_STOP 0xDE
|
||||
#define LLC_SAP_DYN_TRIES 4
|
||||
|
||||
#define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0]))
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __LINUX_LLC_H */
|
||||
@@ -1,32 +0,0 @@
|
||||
#ifndef __LINUX_MODULE_WRAPPER_H
|
||||
#define __LINUX_MODULE_WRAPPER_H 1
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include_next <linux/module.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
static inline int try_module_get(struct module *module)
|
||||
{
|
||||
if (module) {
|
||||
if (module == THIS_MODULE)
|
||||
MOD_INC_USE_COUNT;
|
||||
else
|
||||
printk("warning: try_module_get: module(%p) != THIS_MODULE(%p)\n",
|
||||
module, THIS_MODULE);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void module_put(struct module *module)
|
||||
{
|
||||
if (module) {
|
||||
if (module == THIS_MODULE)
|
||||
MOD_DEC_USE_COUNT;
|
||||
else
|
||||
printk("warning: module_put: module(%p) != THIS_MODULE(%p)\n",
|
||||
module, THIS_MODULE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* module.h */
|
||||
@@ -1,58 +0,0 @@
|
||||
#ifndef __LINUX_MUTEX_H
|
||||
#define __LINUX_MUTEX_H
|
||||
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
struct mutex {
|
||||
struct semaphore sema;
|
||||
};
|
||||
|
||||
#define mutex_init(mutex) init_MUTEX(&mutex->sema)
|
||||
#define mutex_destroy(mutex) do { } while (0)
|
||||
|
||||
#define DEFINE_MUTEX(mutexname) \
|
||||
struct mutex mutexname = { __MUTEX_INITIALIZER(mutexname.sema) }
|
||||
|
||||
/**
|
||||
* mutex_is_locked - is the mutex locked
|
||||
* @lock: the mutex to be queried
|
||||
*
|
||||
* Returns 1 if the mutex is locked, 0 if unlocked.
|
||||
*/
|
||||
static inline int mutex_is_locked(struct mutex *lock)
|
||||
{
|
||||
return sem_getcount(&lock->sema) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* See kernel/mutex.c for detailed documentation of these APIs.
|
||||
* Also see Documentation/mutex-design.txt.
|
||||
*/
|
||||
static inline void mutex_lock(struct mutex *lock)
|
||||
{
|
||||
down(&lock->sema);
|
||||
}
|
||||
|
||||
static inline int mutex_lock_interruptible(struct mutex *lock)
|
||||
{
|
||||
return down_interruptible(&lock->sema);
|
||||
}
|
||||
|
||||
#define mutex_lock_nested(lock, subclass) mutex_lock(lock)
|
||||
#define mutex_lock_interruptible_nested(lock, subclass) mutex_lock_interruptible(lock)
|
||||
|
||||
/*
|
||||
* NOTE: mutex_trylock() follows the spin_trylock() convention,
|
||||
* not the down_trylock() convention!
|
||||
*/
|
||||
static inline int mutex_trylock(struct mutex *lock)
|
||||
{
|
||||
return !down_trylock(&lock->sema);
|
||||
}
|
||||
|
||||
static inline void mutex_unlock(struct mutex *lock)
|
||||
{
|
||||
up(&lock->sema);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,50 +0,0 @@
|
||||
#ifndef __LINUX_NETDEVICE_WRAPPER_H
|
||||
#define __LINUX_NETDEVICE_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/netdevice.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* In 2.6.24, a namespace argument became required for dev_get_by_name.
|
||||
*/
|
||||
#ifdef dev_get_by_name
|
||||
#undef dev_get_by_name
|
||||
#define dev_get_by_name(net, name) \
|
||||
compat_dev_get_by_name((name))
|
||||
static inline struct net_device *compat_dev_get_by_name(const char *name)
|
||||
{
|
||||
return (_set_ver(dev_get_by_name))(name);
|
||||
}
|
||||
#else
|
||||
#define dev_get_by_name(net, name) \
|
||||
dev_get_by_name((name))
|
||||
#endif /* dev_get_by_name */
|
||||
|
||||
#ifdef dev_get_by_index
|
||||
#undef dev_get_by_index
|
||||
#define dev_get_by_index(net, ifindex) \
|
||||
compat_dev_get_by_index((ifindex))
|
||||
static inline struct net_device *compat_dev_get_by_index(int ifindex)
|
||||
{
|
||||
return (_set_ver(dev_get_by_index))(ifindex);
|
||||
}
|
||||
#else
|
||||
#define dev_get_by_index(net, ifindex) \
|
||||
dev_get_by_index((ifindex))
|
||||
#endif /* dev_get_by_index */
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27)
|
||||
static inline void *netdev_priv(struct net_device *dev)
|
||||
{
|
||||
return dev->priv;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Synchronize with packet receive processing. */
|
||||
static inline void synchronize_net(void)
|
||||
{
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,80 +0,0 @@
|
||||
#ifndef __LINUX_NETLINK_WRAPPER_H
|
||||
#define __LINUX_NETLINK_WRAPPER_H 1
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include_next <linux/netlink.h>
|
||||
|
||||
#define NETLINK_GENERIC 16
|
||||
|
||||
#undef NLMSG_LENGTH
|
||||
#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
|
||||
#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
|
||||
|
||||
#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
|
||||
|
||||
enum {
|
||||
NETLINK_UNCONNECTED = 0,
|
||||
NETLINK_CONNECTED,
|
||||
};
|
||||
|
||||
/*
|
||||
* <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
|
||||
* +---------------------+- - -+- - - - - - - - - -+- - -+
|
||||
* | Header | Pad | Payload | Pad |
|
||||
* | (struct nlattr) | ing | | ing |
|
||||
* +---------------------+- - -+- - - - - - - - - -+- - -+
|
||||
* <-------------- nlattr->nla_len -------------->
|
||||
*/
|
||||
|
||||
struct nlattr
|
||||
{
|
||||
__u16 nla_len;
|
||||
__u16 nla_type;
|
||||
};
|
||||
|
||||
#define NLA_ALIGNTO 4
|
||||
#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
|
||||
#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/capability.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct nlmsghdr *)skb->data;
|
||||
}
|
||||
|
||||
#define __nlmsg_put __rpl_nlmsg_put
|
||||
static __inline__ struct nlmsghdr *
|
||||
__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
int size = NLMSG_LENGTH(len);
|
||||
|
||||
nlh = (struct nlmsghdr*)skb_put(skb, NLMSG_ALIGN(size));
|
||||
nlh->nlmsg_type = type;
|
||||
nlh->nlmsg_len = size;
|
||||
nlh->nlmsg_flags = flags;
|
||||
nlh->nlmsg_pid = pid;
|
||||
nlh->nlmsg_seq = seq;
|
||||
memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size);
|
||||
return nlh;
|
||||
}
|
||||
|
||||
#define NLMSG_DEFAULT_SIZE (NLMSG_GOODSIZE - NLMSG_HDRLEN)
|
||||
|
||||
#undef NLMSG_NEW
|
||||
#define NLMSG_NEW(skb, pid, seq, type, len, flags) \
|
||||
({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \
|
||||
goto nlmsg_failure; \
|
||||
__nlmsg_put(skb, pid, seq, type, len, flags); })
|
||||
#endif
|
||||
|
||||
#undef NLMSG_PUT
|
||||
#define NLMSG_PUT(skb, pid, seq, type, len) \
|
||||
NLMSG_NEW(skb, pid, seq, type, len, 0)
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef __LINUX_RANDOM_WRAPPER_H
|
||||
#define __LINUX_RANDOM_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/random.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
u32 random32(void);
|
||||
void srandom32(u32 seed);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,2 +0,0 @@
|
||||
/* In Linux 2.6.26, part of list.h was broken out into rculist.h. */
|
||||
#include <linux/list.h>
|
||||
@@ -1,205 +0,0 @@
|
||||
/*
|
||||
* Read-Copy Update mechanism for mutual exclusion
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Copyright (C) IBM Corporation, 2001
|
||||
*
|
||||
* Author: Dipankar Sarma <dipankar@in.ibm.com>
|
||||
*
|
||||
* Based on the original work by Paul McKenney <paulmck@us.ibm.com>
|
||||
* and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
|
||||
* Papers:
|
||||
* http://www.rdrop.com/users/paulmck/paper/rclockpdcsproof.pdf
|
||||
* http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001)
|
||||
*
|
||||
* For detailed explanation of Read-Copy Update mechanism see -
|
||||
* http://lse.sourceforge.net/locking/rcupdate.html
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_RCUPDATE_H
|
||||
#define __LINUX_RCUPDATE_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/threads.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#error "SMP configurations not supported for RCU backport."
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct rcu_head - callback structure for use with RCU
|
||||
* @next: next update requests in a list
|
||||
* @func: actual update function to call after the grace period.
|
||||
*/
|
||||
struct rcu_head {
|
||||
struct rcu_head *next;
|
||||
void (*func)(struct rcu_head *head);
|
||||
};
|
||||
|
||||
#define RCU_HEAD_INIT { }
|
||||
#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT
|
||||
#define INIT_RCU_HEAD(ptr) do { } while (0)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* rcu_read_lock - mark the beginning of an RCU read-side critical section.
|
||||
*
|
||||
* When synchronize_rcu() is invoked on one CPU while other CPUs
|
||||
* are within RCU read-side critical sections, then the
|
||||
* synchronize_rcu() is guaranteed to block until after all the other
|
||||
* CPUs exit their critical sections. Similarly, if call_rcu() is invoked
|
||||
* on one CPU while other CPUs are within RCU read-side critical
|
||||
* sections, invocation of the corresponding RCU callback is deferred
|
||||
* until after the all the other CPUs exit their critical sections.
|
||||
*
|
||||
* Note, however, that RCU callbacks are permitted to run concurrently
|
||||
* with RCU read-side critical sections. One way that this can happen
|
||||
* is via the following sequence of events: (1) CPU 0 enters an RCU
|
||||
* read-side critical section, (2) CPU 1 invokes call_rcu() to register
|
||||
* an RCU callback, (3) CPU 0 exits the RCU read-side critical section,
|
||||
* (4) CPU 2 enters a RCU read-side critical section, (5) the RCU
|
||||
* callback is invoked. This is legal, because the RCU read-side critical
|
||||
* section that was running concurrently with the call_rcu() (and which
|
||||
* therefore might be referencing something that the corresponding RCU
|
||||
* callback would free up) has completed before the corresponding
|
||||
* RCU callback is invoked.
|
||||
*
|
||||
* RCU read-side critical sections may be nested. Any deferred actions
|
||||
* will be deferred until the outermost RCU read-side critical section
|
||||
* completes.
|
||||
*
|
||||
* It is illegal to block while in an RCU read-side critical section.
|
||||
*/
|
||||
#define rcu_read_lock() \
|
||||
do { } while(0)
|
||||
|
||||
/**
|
||||
* rcu_read_unlock - marks the end of an RCU read-side critical section.
|
||||
*
|
||||
* See rcu_read_lock() for more information.
|
||||
*/
|
||||
#define rcu_read_unlock() \
|
||||
do { } while(0)
|
||||
|
||||
/*
|
||||
* So where is rcu_write_lock()? It does not exist, as there is no
|
||||
* way for writers to lock out RCU readers. This is a feature, not
|
||||
* a bug -- this property is what provides RCU's performance benefits.
|
||||
* Of course, writers must coordinate with each other. The normal
|
||||
* spinlock primitives work well for this, but any other technique may be
|
||||
* used as well. RCU does not care how the writers keep out of each
|
||||
* others' way, as long as they do so.
|
||||
*/
|
||||
|
||||
/**
|
||||
* rcu_read_lock_bh - mark the beginning of a softirq-only RCU critical section
|
||||
*
|
||||
* This is equivalent of rcu_read_lock(), but to be used when updates
|
||||
* are being done using call_rcu_bh(). Since call_rcu_bh() callbacks
|
||||
* consider completion of a softirq handler to be a quiescent state,
|
||||
* a process in RCU read-side critical section must be protected by
|
||||
* disabling softirqs. Read-side critical sections in interrupt context
|
||||
* can use just rcu_read_lock().
|
||||
*
|
||||
*/
|
||||
#define rcu_read_lock_bh() \
|
||||
do { \
|
||||
local_bh_disable(); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* rcu_read_unlock_bh - marks the end of a softirq-only RCU critical section
|
||||
*
|
||||
* See rcu_read_lock_bh() for more information.
|
||||
*/
|
||||
#define rcu_read_unlock_bh() \
|
||||
do { \
|
||||
local_bh_enable(); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* rcu_dereference - fetch an RCU-protected pointer in an
|
||||
* RCU read-side critical section. This pointer may later
|
||||
* be safely dereferenced.
|
||||
*
|
||||
* Inserts memory barriers on architectures that require them
|
||||
* (currently only the Alpha), and, more importantly, documents
|
||||
* exactly which pointers are protected by RCU.
|
||||
*/
|
||||
|
||||
#define rcu_dereference(p) ({ \
|
||||
typeof(p) _________p1 = p; \
|
||||
smp_read_barrier_depends(); \
|
||||
(_________p1); \
|
||||
})
|
||||
|
||||
/**
|
||||
* rcu_assign_pointer - assign (publicize) a pointer to a newly
|
||||
* initialized structure that will be dereferenced by RCU read-side
|
||||
* critical sections. Returns the value assigned.
|
||||
*
|
||||
* Inserts memory barriers on architectures that require them
|
||||
* (pretty much all of them other than x86), and also prevents
|
||||
* the compiler from reordering the code that initializes the
|
||||
* structure after the pointer assignment. More importantly, this
|
||||
* call documents which pointers will be dereferenced by RCU read-side
|
||||
* code.
|
||||
*/
|
||||
|
||||
#define rcu_assign_pointer(p, v) ({ \
|
||||
smp_wmb(); \
|
||||
(p) = (v); \
|
||||
})
|
||||
|
||||
/**
|
||||
* synchronize_sched - block until all CPUs have exited any non-preemptive
|
||||
* kernel code sequences.
|
||||
*
|
||||
* This means that all preempt_disable code sequences, including NMI and
|
||||
* hardware-interrupt handlers, in progress on entry will have completed
|
||||
* before this primitive returns. However, this does not guarantee that
|
||||
* softirq handlers will have completed, since in some kernels, these
|
||||
* handlers can run in process context, and can block.
|
||||
*
|
||||
* This primitive provides the guarantees made by the (now removed)
|
||||
* synchronize_kernel() API. In contrast, synchronize_rcu() only
|
||||
* guarantees that rcu_read_lock() sections will have completed.
|
||||
* In "classic RCU", these two guarantees happen to be one and
|
||||
* the same, but can differ in realtime RCU implementations.
|
||||
*/
|
||||
#define synchronize_sched() synchronize_rcu()
|
||||
|
||||
/* Exported interfaces */
|
||||
void synchronize_rcu(void);
|
||||
void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *head));
|
||||
|
||||
static inline void call_rcu_bh(struct rcu_head *head,
|
||||
void (*func)(struct rcu_head *head))
|
||||
{
|
||||
synchronize_rcu();
|
||||
func(head);
|
||||
}
|
||||
void synchronize_idle(void);
|
||||
extern void rcu_barrier(void);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __LINUX_RCUPDATE_H */
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef __LINUX_SCHED_WRAPPER_H
|
||||
#define __LINUX_SCHED_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/sched.h>
|
||||
|
||||
#include <linux/version.h>
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21)
|
||||
|
||||
#if CONFIG_SMP
|
||||
extern void set_cpus_allowed(struct task_struct *p, unsigned long new_mask);
|
||||
#else
|
||||
# define set_cpus_allowed(p, new_mask) do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* linux kernel < 2.4.21 */
|
||||
|
||||
#endif
|
||||
@@ -1,135 +0,0 @@
|
||||
#ifndef __LINUX_SKBUFF_WRAPPER_H
|
||||
#define __LINUX_SKBUFF_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/skbuff.h>
|
||||
|
||||
|
||||
#define mac_header mac.raw
|
||||
#define network_header nh.raw
|
||||
|
||||
/* Emulate Linux 2.6 behavior, in which kfree_skb silently ignores null pointer
|
||||
* arguments. */
|
||||
#define kfree_skb(skb) kfree_skb_maybe_null(skb)
|
||||
static inline void kfree_skb_maybe_null(struct sk_buff *skb)
|
||||
{
|
||||
if (likely(skb != NULL))
|
||||
(kfree_skb)(skb);
|
||||
}
|
||||
|
||||
/* Note that CHECKSUM_PARTIAL is not implemented, but this allows us to at
|
||||
* least test against it: see update_csum() in forward.c. */
|
||||
#define CHECKSUM_PARTIAL 3
|
||||
#define CHECKSUM_COMPLETE CHECKSUM_HW
|
||||
|
||||
static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->h.raw;
|
||||
}
|
||||
|
||||
static inline void skb_reset_transport_header(struct sk_buff *skb)
|
||||
{
|
||||
skb->h.raw = skb->data;
|
||||
}
|
||||
|
||||
static inline void skb_set_transport_header(struct sk_buff *skb,
|
||||
const int offset)
|
||||
{
|
||||
skb->h.raw = skb->data + offset;
|
||||
}
|
||||
|
||||
static inline unsigned char *skb_network_header(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->nh.raw;
|
||||
}
|
||||
|
||||
static inline void skb_reset_network_header(struct sk_buff *skb)
|
||||
{
|
||||
skb->nh.raw = skb->data;
|
||||
}
|
||||
|
||||
static inline void skb_set_network_header(struct sk_buff *skb, const int offset)
|
||||
{
|
||||
skb->nh.raw = skb->data + offset;
|
||||
}
|
||||
|
||||
static inline unsigned char *skb_mac_header(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->mac.raw;
|
||||
}
|
||||
|
||||
static inline int skb_mac_header_was_set(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->mac.raw != NULL;
|
||||
}
|
||||
|
||||
static inline void skb_reset_mac_header(struct sk_buff *skb)
|
||||
{
|
||||
skb->mac.raw = skb->data;
|
||||
}
|
||||
|
||||
static inline void skb_set_mac_header(struct sk_buff *skb, const int offset)
|
||||
{
|
||||
skb->mac.raw = skb->data + offset;
|
||||
}
|
||||
static inline int skb_transport_offset(const struct sk_buff *skb)
|
||||
{
|
||||
return skb_transport_header(skb) - skb->data;
|
||||
}
|
||||
|
||||
static inline u32 skb_network_header_len(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->h.raw - skb->nh.raw;
|
||||
}
|
||||
|
||||
static inline int skb_network_offset(const struct sk_buff *skb)
|
||||
{
|
||||
return skb_network_header(skb) - skb->data;
|
||||
}
|
||||
|
||||
static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->tail;
|
||||
}
|
||||
|
||||
static inline void skb_reset_tail_pointer(struct sk_buff *skb)
|
||||
{
|
||||
skb->tail = skb->data;
|
||||
}
|
||||
|
||||
static inline void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
|
||||
{
|
||||
skb->tail = skb->data + offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPUs often take a performance hit when accessing unaligned memory
|
||||
* locations. The actual performance hit varies, it can be small if the
|
||||
* hardware handles it or large if we have to take an exception and fix it
|
||||
* in software.
|
||||
*
|
||||
* Since an ethernet header is 14 bytes network drivers often end up with
|
||||
* the IP header at an unaligned offset. The IP header can be aligned by
|
||||
* shifting the start of the packet by 2 bytes. Drivers should do this
|
||||
* with:
|
||||
*
|
||||
* skb_reserve(NET_IP_ALIGN);
|
||||
*
|
||||
* The downside to this alignment of the IP header is that the DMA is now
|
||||
* unaligned. On some architectures the cost of an unaligned DMA is high
|
||||
* and this cost outweighs the gains made by aligning the IP header.
|
||||
*
|
||||
* Since this trade off varies between architectures, we allow NET_IP_ALIGN
|
||||
* to be overridden.
|
||||
*/
|
||||
#ifndef NET_IP_ALIGN
|
||||
#define NET_IP_ALIGN 2
|
||||
#endif
|
||||
|
||||
static inline void skb_copy_to_linear_data(struct sk_buff *skb,
|
||||
const void *from,
|
||||
const unsigned int len)
|
||||
{
|
||||
memcpy(skb->data, from, len);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef __LINUX_SLAB_WRAPPER_H
|
||||
#define __LINUX_SLAB_WRAPPER_H 1
|
||||
|
||||
/* Kluge to let "struct kmem_cache" work in both 2.4 and 2.6. */
|
||||
#define kmem_cache_s kmem_cache
|
||||
|
||||
#include_next <linux/slab.h>
|
||||
|
||||
static inline void *kzalloc(size_t size, gfp_t flags)
|
||||
{
|
||||
void *p = kmalloc(size, flags);
|
||||
if (p)
|
||||
memset(p, 0, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Mega-kluge to wrap 2.4 kmem_cache_create for compatibility with 2.6. */
|
||||
#ifdef kmem_cache_create
|
||||
#undef kmem_cache_create
|
||||
#define kmem_cache_create(name, size, align, flags, ctor) \
|
||||
compat_kmem_cache_create(name, size, align, flags, ctor)
|
||||
static inline struct kmem_cache *
|
||||
compat_kmem_cache_create(const char *name, size_t size,
|
||||
size_t align, unsigned long flags,
|
||||
void (*ctor)(void *, struct kmem_cache *,
|
||||
unsigned long))
|
||||
{
|
||||
return (_set_ver(kmem_cache_create))(name, size, align, flags, ctor,
|
||||
NULL);
|
||||
}
|
||||
#else
|
||||
#define kmem_cache_create(name, size, align, flags, ctor) \
|
||||
kmem_cache_create(name, size, align, flags, ctor, NULL)
|
||||
#endif /* kmem_cache_create */
|
||||
|
||||
static inline void *kmem_cache_zalloc(struct kmem_cache *k, gfp_t flags)
|
||||
{
|
||||
void *p = kmem_cache_alloc(k, flags);
|
||||
if (p)
|
||||
memset(p, 0, kmem_cache_size(k));
|
||||
return p;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef __LINUX_SOCKIOS_WRAPPER_H
|
||||
#define __LINUX_SOCKIOS_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/sockios.h>
|
||||
|
||||
/* bridge calls */
|
||||
#define SIOCBRADDBR 0x89a0 /* create new bridge device */
|
||||
#define SIOCBRDELBR 0x89a1 /* remove bridge device */
|
||||
#define SIOCBRADDIF 0x89a2 /* add interface to bridge */
|
||||
#define SIOCBRDELIF 0x89a3 /* remove interface from bridge */
|
||||
|
||||
#endif
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef __LINUX_SPINLOCK_WRAPPER_H
|
||||
#define __LINUX_SPINLOCK_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/spinlock.h>
|
||||
|
||||
#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
|
||||
|
||||
#endif /* linux/spinlock.h */
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef __LINUX_STRING_WRAPPER_H
|
||||
#define __LINUX_STRING_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/string.h>
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCSPN
|
||||
size_t strcspn(const char *s, const char *reject);
|
||||
#endif
|
||||
|
||||
size_t strlcpy(char *, const char *, size_t);
|
||||
|
||||
#endif /* linux/string.h */
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef __LINUX_TCP_WRAPPER_H
|
||||
#define __LINUX_TCP_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/tcp.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
static inline struct tcphdr *tcp_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct tcphdr *)skb_transport_header(skb);
|
||||
}
|
||||
|
||||
static inline unsigned int tcp_hdrlen(const struct sk_buff *skb)
|
||||
{
|
||||
return tcp_hdr(skb)->doff * 4;
|
||||
}
|
||||
|
||||
static inline unsigned int tcp_optlen(const struct sk_buff *skb)
|
||||
{
|
||||
return (tcp_hdr(skb)->doff - 5) * 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef __LINUX_TIME_WRAPPER_H
|
||||
#define __LINUX_TIME_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/time.h>
|
||||
|
||||
/* Parameters used to convert the timespec values: */
|
||||
#define MSEC_PER_SEC 1000L
|
||||
#define USEC_PER_MSEC 1000L
|
||||
#define NSEC_PER_USEC 1000L
|
||||
#define NSEC_PER_MSEC 1000000L
|
||||
#define USEC_PER_SEC 1000000L
|
||||
#define NSEC_PER_SEC 1000000000L
|
||||
#define FSEC_PER_SEC 1000000000000000L
|
||||
|
||||
#endif
|
||||
@@ -1,96 +0,0 @@
|
||||
#ifndef __LINUX_TIMER_WRAPPER_H
|
||||
#define __LINUX_TIMER_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/timer.h>
|
||||
#include <asm/param.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
extern unsigned long volatile jiffies;
|
||||
|
||||
static inline void setup_timer(struct timer_list * timer,
|
||||
void (*function)(unsigned long),
|
||||
unsigned long data)
|
||||
{
|
||||
timer->function = function;
|
||||
timer->data = data;
|
||||
init_timer(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* __round_jiffies - function to round jiffies to a full second
|
||||
* @j: the time in (absolute) jiffies that should be rounded
|
||||
* @cpu: the processor number on which the timeout will happen
|
||||
*
|
||||
* __round_jiffies() rounds an absolute time in the future (in jiffies)
|
||||
* up or down to (approximately) full seconds. This is useful for timers
|
||||
* for which the exact time they fire does not matter too much, as long as
|
||||
* they fire approximately every X seconds.
|
||||
*
|
||||
* By rounding these timers to whole seconds, all such timers will fire
|
||||
* at the same time, rather than at various times spread out. The goal
|
||||
* of this is to have the CPU wake up less, which saves power.
|
||||
*
|
||||
* The exact rounding is skewed for each processor to avoid all
|
||||
* processors firing at the exact same time, which could lead
|
||||
* to lock contention or spurious cache line bouncing.
|
||||
*
|
||||
* The return value is the rounded version of the @j parameter.
|
||||
*/
|
||||
static inline unsigned long __round_jiffies(unsigned long j, int cpu)
|
||||
{
|
||||
int rem;
|
||||
unsigned long original = j;
|
||||
|
||||
/*
|
||||
* We don't want all cpus firing their timers at once hitting the
|
||||
* same lock or cachelines, so we skew each extra cpu with an extra
|
||||
* 3 jiffies. This 3 jiffies came originally from the mm/ code which
|
||||
* already did this.
|
||||
* The skew is done by adding 3*cpunr, then round, then subtract this
|
||||
* extra offset again.
|
||||
*/
|
||||
j += cpu * 3;
|
||||
|
||||
rem = j % HZ;
|
||||
|
||||
/*
|
||||
* If the target jiffie is just after a whole second (which can happen
|
||||
* due to delays of the timer irq, long irq off times etc etc) then
|
||||
* we should round down to the whole second, not up. Use 1/4th second
|
||||
* as cutoff for this rounding as an extreme upper bound for this.
|
||||
*/
|
||||
if (rem < HZ/4) /* round down */
|
||||
j = j - rem;
|
||||
else /* round up */
|
||||
j = j - rem + HZ;
|
||||
|
||||
/* now that we have rounded, subtract the extra skew again */
|
||||
j -= cpu * 3;
|
||||
|
||||
if (j <= jiffies) /* rounding ate our timeout entirely; */
|
||||
return original;
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* round_jiffies - function to round jiffies to a full second
|
||||
* @j: the time in (absolute) jiffies that should be rounded
|
||||
*
|
||||
* round_jiffies() rounds an absolute time in the future (in jiffies)
|
||||
* up or down to (approximately) full seconds. This is useful for timers
|
||||
* for which the exact time they fire does not matter too much, as long as
|
||||
* they fire approximately every X seconds.
|
||||
*
|
||||
* By rounding these timers to whole seconds, all such timers will fire
|
||||
* at the same time, rather than at various times spread out. The goal
|
||||
* of this is to have the CPU wake up less, which saves power.
|
||||
*
|
||||
* The return value is the rounded version of the @j parameter.
|
||||
*/
|
||||
static inline unsigned long round_jiffies(unsigned long j)
|
||||
{
|
||||
return __round_jiffies(j, 0); // FIXME
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
#ifndef __LINUX_TYPES_WRAPPER_H
|
||||
#define __LINUX_TYPES_WRAPPER_H 1
|
||||
|
||||
#include <linux/version.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
|
||||
#error These replacement header files are for use with Linux 2.4.x only.
|
||||
#endif
|
||||
|
||||
#include_next <linux/types.h>
|
||||
|
||||
/*
|
||||
* Below are truly Linux-specific types that should never collide with
|
||||
* any application/library that wants linux/types.h.
|
||||
*/
|
||||
|
||||
#ifdef __CHECKER__
|
||||
#define __bitwise__ __attribute__((bitwise))
|
||||
#else
|
||||
#define __bitwise__
|
||||
#endif
|
||||
#ifdef __CHECK_ENDIAN__
|
||||
#define __bitwise __bitwise__
|
||||
#else
|
||||
#define __bitwise
|
||||
#endif
|
||||
|
||||
typedef __u16 __bitwise __le16;
|
||||
typedef __u16 __bitwise __be16;
|
||||
typedef __u32 __bitwise __le32;
|
||||
typedef __u32 __bitwise __be32;
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
typedef __u64 __bitwise __le64;
|
||||
typedef __u64 __bitwise __be64;
|
||||
#endif
|
||||
typedef __u16 __bitwise __sum16;
|
||||
typedef __u32 __bitwise __wsum;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
typedef unsigned __bitwise__ gfp_t;
|
||||
|
||||
#ifdef CONFIG_RESOURCES_64BIT
|
||||
typedef u64 resource_size_t;
|
||||
#else
|
||||
typedef u32 resource_size_t;
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef __LINUX_UDP_WRAPPER_H
|
||||
#define __LINUX_UDP_WRAPPER_H 1
|
||||
|
||||
#include_next <linux/udp.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct udphdr *)skb_transport_header(skb);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef __LINUX_WORKQUEUE_H
|
||||
#define __LINUX_WORKQUEUE_H 1
|
||||
|
||||
#include <linux/tqueue.h>
|
||||
|
||||
#define work_struct tq_struct
|
||||
|
||||
#define INIT_WORK(_work, _routine) \
|
||||
INIT_TQUEUE((_work), ((void *)_routine), (_work))
|
||||
|
||||
#define PREPARE_WORK(_work, _routine) \
|
||||
PREPARE_TQUEUE((_work), ((void *)_routine), (_work))
|
||||
|
||||
#define schedule_work(_work) schedule_task(_work)
|
||||
|
||||
#define flush_scheduled_work() flush_scheduled_tasks()
|
||||
|
||||
/* There is no equivalent to cancel_work_sync() in 2.4, so just flush all
|
||||
* pending tasks. */
|
||||
#define cancel_work_sync(_work) flush_scheduled_tasks()
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef __NET_CHECKSUM_WRAPPER_H
|
||||
#define __NET_CHECKSUM_WRAPPER_H 1
|
||||
|
||||
#include_next <net/checksum.h>
|
||||
|
||||
static inline __wsum csum_unfold(__sum16 n)
|
||||
{
|
||||
return (__force __wsum)n;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,252 +0,0 @@
|
||||
#ifndef __NET_GENERIC_NETLINK_H
|
||||
#define __NET_GENERIC_NETLINK_H
|
||||
|
||||
#include <linux/genetlink.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
/**
|
||||
* struct genl_multicast_group - generic netlink multicast group
|
||||
* @name: name of the multicast group, names are per-family
|
||||
* @id: multicast group ID, assigned by the core, to use with
|
||||
* genlmsg_multicast().
|
||||
* @list: list entry for linking
|
||||
* @family: pointer to family, need not be set before registering
|
||||
*/
|
||||
struct genl_multicast_group
|
||||
{
|
||||
struct genl_family *family; /* private */
|
||||
struct list_head list; /* private */
|
||||
char name[GENL_NAMSIZ];
|
||||
u32 id;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct genl_family - generic netlink family
|
||||
* @id: protocol family idenfitier
|
||||
* @hdrsize: length of user specific header in bytes
|
||||
* @name: name of family
|
||||
* @version: protocol version
|
||||
* @maxattr: maximum number of attributes supported
|
||||
* @attrbuf: buffer to store parsed attributes
|
||||
* @ops_list: list of all assigned operations
|
||||
* @family_list: family list
|
||||
* @mcast_groups: multicast groups list
|
||||
*/
|
||||
struct genl_family
|
||||
{
|
||||
unsigned int id;
|
||||
unsigned int hdrsize;
|
||||
char name[GENL_NAMSIZ];
|
||||
unsigned int version;
|
||||
unsigned int maxattr;
|
||||
struct nlattr ** attrbuf; /* private */
|
||||
struct list_head ops_list; /* private */
|
||||
struct list_head family_list; /* private */
|
||||
struct list_head mcast_groups; /* private */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct genl_info - receiving information
|
||||
* @snd_seq: sending sequence number
|
||||
* @snd_pid: netlink pid of sender
|
||||
* @nlhdr: netlink message header
|
||||
* @genlhdr: generic netlink message header
|
||||
* @userhdr: user specific header
|
||||
* @attrs: netlink attributes
|
||||
*/
|
||||
struct genl_info
|
||||
{
|
||||
u32 snd_seq;
|
||||
u32 snd_pid;
|
||||
struct nlmsghdr * nlhdr;
|
||||
struct genlmsghdr * genlhdr;
|
||||
void * userhdr;
|
||||
struct nlattr ** attrs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct genl_ops - generic netlink operations
|
||||
* @cmd: command identifier
|
||||
* @flags: flags
|
||||
* @policy: attribute validation policy
|
||||
* @doit: standard command callback
|
||||
* @dumpit: callback for dumpers
|
||||
* @done: completion callback for dumps
|
||||
* @ops_list: operations list
|
||||
*/
|
||||
struct genl_ops
|
||||
{
|
||||
u8 cmd;
|
||||
unsigned int flags;
|
||||
const struct nla_policy *policy;
|
||||
int (*doit)(struct sk_buff *skb,
|
||||
struct genl_info *info);
|
||||
int (*dumpit)(struct sk_buff *skb,
|
||||
struct netlink_callback *cb);
|
||||
int (*done)(struct netlink_callback *cb);
|
||||
struct list_head ops_list;
|
||||
};
|
||||
|
||||
extern int genl_register_family(struct genl_family *family);
|
||||
extern int genl_unregister_family(struct genl_family *family);
|
||||
extern int genl_register_ops(struct genl_family *, struct genl_ops *ops);
|
||||
extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
|
||||
extern int genl_register_mc_group(struct genl_family *family,
|
||||
struct genl_multicast_group *grp);
|
||||
extern void genl_unregister_mc_group(struct genl_family *family,
|
||||
struct genl_multicast_group *grp);
|
||||
|
||||
extern struct sock *genl_sock;
|
||||
|
||||
/**
|
||||
* genlmsg_put - Add generic netlink header to netlink message
|
||||
* @skb: socket buffer holding the message
|
||||
* @pid: netlink pid the message is addressed to
|
||||
* @seq: sequence number (usually the one of the sender)
|
||||
* @family: generic netlink family
|
||||
* @flags netlink message flags
|
||||
* @cmd: generic netlink command
|
||||
*
|
||||
* Returns pointer to user specific header
|
||||
*/
|
||||
static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq,
|
||||
struct genl_family *family, int flags, u8 cmd)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct genlmsghdr *hdr;
|
||||
|
||||
nlh = nlmsg_put(skb, pid, seq, family->id, GENL_HDRLEN +
|
||||
family->hdrsize, flags);
|
||||
if (nlh == NULL)
|
||||
return NULL;
|
||||
|
||||
hdr = nlmsg_data(nlh);
|
||||
hdr->cmd = cmd;
|
||||
hdr->version = family->version;
|
||||
hdr->reserved = 0;
|
||||
|
||||
return (char *) hdr + GENL_HDRLEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_put_reply - Add generic netlink header to a reply message
|
||||
* @skb: socket buffer holding the message
|
||||
* @info: receiver info
|
||||
* @family: generic netlink family
|
||||
* @flags: netlink message flags
|
||||
* @cmd: generic netlink command
|
||||
*
|
||||
* Returns pointer to user specific header
|
||||
*/
|
||||
static inline void *genlmsg_put_reply(struct sk_buff *skb,
|
||||
struct genl_info *info,
|
||||
struct genl_family *family,
|
||||
int flags, u8 cmd)
|
||||
{
|
||||
return genlmsg_put(skb, info->snd_pid, info->snd_seq, family,
|
||||
flags, cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_end - Finalize a generic netlink message
|
||||
* @skb: socket buffer the message is stored in
|
||||
* @hdr: user specific header
|
||||
*/
|
||||
static inline int genlmsg_end(struct sk_buff *skb, void *hdr)
|
||||
{
|
||||
return nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_cancel - Cancel construction of a generic netlink message
|
||||
* @skb: socket buffer the message is stored in
|
||||
* @hdr: generic netlink message header
|
||||
*/
|
||||
static inline int genlmsg_cancel(struct sk_buff *skb, void *hdr)
|
||||
{
|
||||
return nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_multicast - multicast a netlink message
|
||||
* @skb: netlink message as socket buffer
|
||||
* @pid: own netlink pid to avoid sending to yourself
|
||||
* @group: multicast group id
|
||||
* @flags: allocation flags
|
||||
*/
|
||||
static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
|
||||
unsigned int group, gfp_t flags)
|
||||
{
|
||||
return nlmsg_multicast(genl_sock, skb, pid, group, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_unicast - unicast a netlink message
|
||||
* @skb: netlink message as socket buffer
|
||||
* @pid: netlink pid of the destination socket
|
||||
*/
|
||||
static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
|
||||
{
|
||||
return nlmsg_unicast(genl_sock, skb, pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_reply - reply to a request
|
||||
* @skb: netlink message to be sent back
|
||||
* @info: receiver information
|
||||
*/
|
||||
static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return genlmsg_unicast(skb, info->snd_pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* gennlmsg_data - head of message payload
|
||||
* @gnlh: genetlink messsage header
|
||||
*/
|
||||
static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
|
||||
{
|
||||
return ((unsigned char *) gnlh + GENL_HDRLEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_len - length of message payload
|
||||
* @gnlh: genetlink message header
|
||||
*/
|
||||
static inline int genlmsg_len(const struct genlmsghdr *gnlh)
|
||||
{
|
||||
struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
|
||||
NLMSG_HDRLEN);
|
||||
return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_msg_size - length of genetlink message not including padding
|
||||
* @payload: length of message payload
|
||||
*/
|
||||
static inline int genlmsg_msg_size(int payload)
|
||||
{
|
||||
return GENL_HDRLEN + payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_total_size - length of genetlink message including padding
|
||||
* @payload: length of message payload
|
||||
*/
|
||||
static inline int genlmsg_total_size(int payload)
|
||||
{
|
||||
return NLMSG_ALIGN(genlmsg_msg_size(payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_new - Allocate a new generic netlink message
|
||||
* @payload: size of the message payload
|
||||
* @flags: the type of memory to allocate.
|
||||
*/
|
||||
static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
|
||||
{
|
||||
return nlmsg_new(genlmsg_total_size(payload), flags);
|
||||
}
|
||||
|
||||
|
||||
#endif /* __NET_GENERIC_NETLINK_H */
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef __NET_LLC_PDU_H
|
||||
#define __NET_LLC_PDU_H 1
|
||||
|
||||
/* Un-numbered PDU format (3 bytes in length) */
|
||||
struct llc_pdu_un {
|
||||
u8 dsap;
|
||||
u8 ssap;
|
||||
u8 ctrl_1;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Distributed under the terms of the GNU GPL version 2.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/hardirq.h>
|
||||
|
||||
int vprintk(const char *msg, ...)
|
||||
{
|
||||
#define BUFFER_SIZE 1024
|
||||
char *buffer = kmalloc(BUFFER_SIZE, GFP_ATOMIC);
|
||||
int retval;
|
||||
if (buffer) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
vsnprintf(buffer, BUFFER_SIZE, msg, args);
|
||||
va_end(args);
|
||||
retval = printk("%s", buffer);
|
||||
kfree(buffer);
|
||||
} else {
|
||||
retval = printk("<<vprintk allocation failure>> %s", msg);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(vprintk);
|
||||
|
||||
#ifdef CONFIG_DEBUG_SPINLOCK
|
||||
void __might_sleep(char *file, int line)
|
||||
{
|
||||
static unsigned long prev_jiffy; /* ratelimiting */
|
||||
|
||||
if ((in_interrupt()) && !oops_in_progress) {
|
||||
if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
|
||||
return;
|
||||
prev_jiffy = jiffies;
|
||||
printk(KERN_ERR "BUG: sleeping function called from invalid"
|
||||
" context at %s:%d\n", file, line);
|
||||
dump_stack();
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(__might_sleep);
|
||||
#endif
|
||||
@@ -1,260 +0,0 @@
|
||||
/* Kernel thread helper functions.
|
||||
* Copyright (C) 2004 IBM Corporation, Rusty Russell.
|
||||
*
|
||||
* Creation is done via kthreadd, so that we get a clean environment
|
||||
* even if we're invoked from userspace (think modprobe, hotplug cpu,
|
||||
* etc.).
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <asm/smplock.h>
|
||||
#include "compat24.h"
|
||||
|
||||
static DEFINE_SPINLOCK(kthread_create_lock);
|
||||
static LIST_HEAD(kthread_create_list);
|
||||
struct task_struct *kthreadd_task;
|
||||
|
||||
struct kthread_create_info
|
||||
{
|
||||
/* Information passed to kthread() from kthreadd. */
|
||||
int (*threadfn)(void *data);
|
||||
void *data;
|
||||
struct completion started;
|
||||
|
||||
/* Result passed back to kthread_create() from kthreadd. */
|
||||
struct task_struct *result;
|
||||
struct completion done;
|
||||
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct kthread_stop_info
|
||||
{
|
||||
struct task_struct *k;
|
||||
int err;
|
||||
struct completion done;
|
||||
};
|
||||
|
||||
/* Thread stopping is done by setthing this var: lock serializes
|
||||
* multiple kthread_stop calls. */
|
||||
static DEFINE_MUTEX(kthread_stop_lock);
|
||||
static struct kthread_stop_info kthread_stop_info;
|
||||
|
||||
/**
|
||||
* kthread_should_stop - should this kthread return now?
|
||||
*
|
||||
* When someone calls kthread_stop() on your kthread, it will be woken
|
||||
* and this will return true. You should then return, and your return
|
||||
* value will be passed through to kthread_stop().
|
||||
*/
|
||||
int kthread_should_stop(void)
|
||||
{
|
||||
return (kthread_stop_info.k == current);
|
||||
}
|
||||
EXPORT_SYMBOL(kthread_should_stop);
|
||||
|
||||
static int kthread(void *_create)
|
||||
{
|
||||
struct kthread_create_info *create = _create;
|
||||
int (*threadfn)(void *data);
|
||||
void *data;
|
||||
int ret = -EINTR;
|
||||
|
||||
/* Copy data: it's on kthread's stack */
|
||||
threadfn = create->threadfn;
|
||||
data = create->data;
|
||||
|
||||
/* OK, tell user we're spawned, wait for stop or wakeup */
|
||||
__set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
complete(&create->started);
|
||||
schedule();
|
||||
|
||||
if (!kthread_should_stop())
|
||||
ret = threadfn(data);
|
||||
|
||||
/* It might have exited on its own, w/o kthread_stop. Check. */
|
||||
if (kthread_should_stop()) {
|
||||
kthread_stop_info.err = ret;
|
||||
complete(&kthread_stop_info.done);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void create_kthread(struct kthread_create_info *create)
|
||||
{
|
||||
int pid;
|
||||
|
||||
/* We want our own signal handler (we take no signals by default). */
|
||||
pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
|
||||
if (pid < 0) {
|
||||
create->result = ERR_PTR(pid);
|
||||
} else {
|
||||
wait_for_completion(&create->started);
|
||||
read_lock(&tasklist_lock);
|
||||
create->result = find_task_by_pid(pid);
|
||||
read_unlock(&tasklist_lock);
|
||||
}
|
||||
complete(&create->done);
|
||||
}
|
||||
|
||||
/**
|
||||
* kthread_create - create a kthread.
|
||||
* @threadfn: the function to run until signal_pending(current).
|
||||
* @data: data ptr for @threadfn.
|
||||
* @namefmt: printf-style name for the thread.
|
||||
*
|
||||
* Description: This helper function creates and names a kernel
|
||||
* thread. The thread will be stopped: use wake_up_process() to start
|
||||
* it. See also kthread_run(), kthread_create_on_cpu().
|
||||
*
|
||||
* When woken, the thread will run @threadfn() with @data as its
|
||||
* argument. @threadfn() can either call do_exit() directly if it is a
|
||||
* standalone thread for which noone will call kthread_stop(), or
|
||||
* return when 'kthread_should_stop()' is true (which means
|
||||
* kthread_stop() has been called). The return value should be zero
|
||||
* or a negative error number; it will be passed to kthread_stop().
|
||||
*
|
||||
* Returns a task_struct or ERR_PTR(-ENOMEM).
|
||||
*/
|
||||
struct task_struct *kthread_create(int (*threadfn)(void *data),
|
||||
void *data,
|
||||
const char namefmt[],
|
||||
...)
|
||||
{
|
||||
struct kthread_create_info create;
|
||||
|
||||
create.threadfn = threadfn;
|
||||
create.data = data;
|
||||
init_completion(&create.started);
|
||||
init_completion(&create.done);
|
||||
|
||||
spin_lock(&kthread_create_lock);
|
||||
list_add_tail(&create.list, &kthread_create_list);
|
||||
wake_up_process(kthreadd_task);
|
||||
spin_unlock(&kthread_create_lock);
|
||||
|
||||
wait_for_completion(&create.done);
|
||||
|
||||
if (!IS_ERR(create.result)) {
|
||||
va_list args;
|
||||
va_start(args, namefmt);
|
||||
vsnprintf(create.result->comm, sizeof(create.result->comm),
|
||||
namefmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
return create.result;
|
||||
}
|
||||
EXPORT_SYMBOL(kthread_create);
|
||||
|
||||
/**
|
||||
* kthread_stop - stop a thread created by kthread_create().
|
||||
* @k: thread created by kthread_create().
|
||||
*
|
||||
* Sets kthread_should_stop() for @k to return true, wakes it, and
|
||||
* waits for it to exit. Your threadfn() must not call do_exit()
|
||||
* itself if you use this function! This can also be called after
|
||||
* kthread_create() instead of calling wake_up_process(): the thread
|
||||
* will exit without calling threadfn().
|
||||
*
|
||||
* Returns the result of threadfn(), or %-EINTR if wake_up_process()
|
||||
* was never called.
|
||||
*/
|
||||
int kthread_stop(struct task_struct *k)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&kthread_stop_lock);
|
||||
|
||||
/* Thread exit requires BKL, so prevent it while while we're messing
|
||||
* with the thread. */
|
||||
lock_kernel();
|
||||
|
||||
/* Must init completion *before* thread sees kthread_stop_info.k */
|
||||
init_completion(&kthread_stop_info.done);
|
||||
smp_wmb();
|
||||
|
||||
/* Now set kthread_should_stop() to true, and wake it up. */
|
||||
kthread_stop_info.k = k;
|
||||
wake_up_process(k);
|
||||
|
||||
unlock_kernel();
|
||||
|
||||
/* Once it dies, reset stop ptr, gather result and we're done. */
|
||||
wait_for_completion(&kthread_stop_info.done);
|
||||
kthread_stop_info.k = NULL;
|
||||
ret = kthread_stop_info.err;
|
||||
mutex_unlock(&kthread_stop_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(kthread_stop);
|
||||
|
||||
void ignore_signals(struct task_struct *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _NSIG; ++i)
|
||||
t->sig->action[i].sa.sa_handler = SIG_IGN;
|
||||
|
||||
flush_signals(t);
|
||||
}
|
||||
|
||||
/* This is a copy of the set_task_comm() function, which is not exported to
|
||||
* modules. */
|
||||
static void do_set_task_comm(struct task_struct *tsk, char *buf)
|
||||
{
|
||||
task_lock(tsk);
|
||||
strncpy(tsk->comm, buf, sizeof(tsk->comm));
|
||||
tsk->comm[sizeof(tsk->comm)-1]='\0';
|
||||
task_unlock(tsk);
|
||||
}
|
||||
|
||||
int kthreadd(void *unused)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
/* Setup a clean context for our children to inherit. */
|
||||
do_set_task_comm(tsk, "kthreadd");
|
||||
ignore_signals(tsk);
|
||||
tsk->nice = -5;
|
||||
set_cpus_allowed(tsk, CPU_MASK_ALL);
|
||||
|
||||
for (;;) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
if (list_empty(&kthread_create_list))
|
||||
schedule();
|
||||
__set_current_state(TASK_RUNNING);
|
||||
|
||||
spin_lock(&kthread_create_lock);
|
||||
while (!list_empty(&kthread_create_list)) {
|
||||
struct kthread_create_info *create;
|
||||
|
||||
create = list_entry(kthread_create_list.next,
|
||||
struct kthread_create_info, list);
|
||||
list_del_init(&create->list);
|
||||
spin_unlock(&kthread_create_lock);
|
||||
|
||||
create_kthread(create);
|
||||
|
||||
spin_lock(&kthread_create_lock);
|
||||
}
|
||||
spin_unlock(&kthread_create_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_kthread(void)
|
||||
{
|
||||
int pid;
|
||||
|
||||
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
|
||||
kthreadd_task = find_task_by_pid(pid);
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* NETLINK Netlink attributes
|
||||
*
|
||||
* Authors: Thomas Graf <tgraf@suug.ch>
|
||||
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/types.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
/**
|
||||
* netlink_queue_skip - Skip netlink message while processing queue.
|
||||
* @nlh: Netlink message to be skipped
|
||||
* @skb: Socket buffer containing the netlink messages.
|
||||
*
|
||||
* Pulls the given netlink message off the socket buffer so the next
|
||||
* call to netlink_queue_run() will not reconsider the message.
|
||||
*/
|
||||
static void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb)
|
||||
{
|
||||
int msglen = NLMSG_ALIGN(nlh->nlmsg_len);
|
||||
|
||||
if (msglen > skb->len)
|
||||
msglen = skb->len;
|
||||
|
||||
skb_pull(skb, msglen);
|
||||
}
|
||||
|
||||
static int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
|
||||
struct nlmsghdr *))
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
int err;
|
||||
|
||||
while (skb->len >= nlmsg_total_size(0)) {
|
||||
nlh = nlmsg_hdr(skb);
|
||||
err = 0;
|
||||
|
||||
if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
|
||||
return 0;
|
||||
|
||||
/* Only requests are handled by the kernel */
|
||||
if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
|
||||
goto skip;
|
||||
|
||||
/* Skip control messages */
|
||||
if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
|
||||
goto skip;
|
||||
|
||||
err = cb(skb, nlh);
|
||||
if (err == -EINTR) {
|
||||
/* Not an error, but we interrupt processing */
|
||||
netlink_queue_skip(nlh, skb);
|
||||
return err;
|
||||
}
|
||||
skip:
|
||||
if (nlh->nlmsg_flags & NLM_F_ACK || err)
|
||||
netlink_ack(skb, nlh, err);
|
||||
|
||||
netlink_queue_skip(nlh, skb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* netlink_run_queue - Process netlink receive queue.
|
||||
* @sk: Netlink socket containing the queue
|
||||
* @qlen: Place to store queue length upon entry
|
||||
* @cb: Callback function invoked for each netlink message found
|
||||
*
|
||||
* Processes as much as there was in the queue upon entry and invokes
|
||||
* a callback function for each netlink message found. The callback
|
||||
* function may refuse a message by returning a negative error code
|
||||
* but setting the error pointer to 0 in which case this function
|
||||
* returns with a qlen != 0.
|
||||
*
|
||||
* qlen must be initialized to 0 before the initial entry, afterwards
|
||||
* the function may be called repeatedly until qlen reaches 0.
|
||||
*
|
||||
* The callback function may return -EINTR to signal that processing
|
||||
* of netlink messages shall be interrupted. In this case the message
|
||||
* currently being processed will NOT be requeued onto the receive
|
||||
* queue.
|
||||
*/
|
||||
void netlink_run_queue(struct sock *sk, unsigned int *qlen,
|
||||
int (*cb)(struct sk_buff *, struct nlmsghdr *))
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!*qlen || *qlen > skb_queue_len(&sk->receive_queue))
|
||||
*qlen = skb_queue_len(&sk->receive_queue);
|
||||
|
||||
for (; *qlen; (*qlen)--) {
|
||||
skb = skb_dequeue(&sk->receive_queue);
|
||||
if (netlink_rcv_skb(skb, cb)) {
|
||||
if (skb->len)
|
||||
skb_queue_head(&sk->receive_queue, skb);
|
||||
else {
|
||||
kfree_skb(skb);
|
||||
(*qlen)--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
This is a maximally equidistributed combined Tausworthe generator
|
||||
based on code from GNU Scientific Library 1.5 (30 Jun 2004)
|
||||
|
||||
x_n = (s1_n ^ s2_n ^ s3_n)
|
||||
|
||||
s1_{n+1} = (((s1_n & 4294967294) <<12) ^ (((s1_n <<13) ^ s1_n) >>19))
|
||||
s2_{n+1} = (((s2_n & 4294967288) << 4) ^ (((s2_n << 2) ^ s2_n) >>25))
|
||||
s3_{n+1} = (((s3_n & 4294967280) <<17) ^ (((s3_n << 3) ^ s3_n) >>11))
|
||||
|
||||
The period of this generator is about 2^88.
|
||||
|
||||
From: P. L'Ecuyer, "Maximally Equidistributed Combined Tausworthe
|
||||
Generators", Mathematics of Computation, 65, 213 (1996), 203--213.
|
||||
|
||||
This is available on the net from L'Ecuyer's home page,
|
||||
|
||||
http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
|
||||
ftp://ftp.iro.umontreal.ca/pub/simulation/lecuyer/papers/tausme.ps
|
||||
|
||||
There is an erratum in the paper "Tables of Maximally
|
||||
Equidistributed Combined LFSR Generators", Mathematics of
|
||||
Computation, 68, 225 (1999), 261--269:
|
||||
http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps
|
||||
|
||||
... the k_j most significant bits of z_j must be non-
|
||||
zero, for each j. (Note: this restriction also applies to the
|
||||
computer code given in [4], but was mistakenly not mentioned in
|
||||
that paper.)
|
||||
|
||||
This affects the seeding procedure by imposing the requirement
|
||||
s1 > 1, s2 > 7, s3 > 15.
|
||||
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/threads.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include "compat24.h"
|
||||
|
||||
struct rnd_state {
|
||||
u32 s1, s2, s3;
|
||||
};
|
||||
|
||||
static struct rnd_state net_rand_state[NR_CPUS];
|
||||
|
||||
static u32 __random32(struct rnd_state *state)
|
||||
{
|
||||
#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)
|
||||
|
||||
state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
|
||||
state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
|
||||
state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);
|
||||
|
||||
return (state->s1 ^ state->s2 ^ state->s3);
|
||||
}
|
||||
|
||||
static void __set_random32(struct rnd_state *state, unsigned long s)
|
||||
{
|
||||
if (s == 0)
|
||||
s = 1; /* default seed is 1 */
|
||||
|
||||
#define LCG(n) (69069 * n)
|
||||
state->s1 = LCG(s);
|
||||
state->s2 = LCG(state->s1);
|
||||
state->s3 = LCG(state->s2);
|
||||
|
||||
/* "warm it up" */
|
||||
__random32(state);
|
||||
__random32(state);
|
||||
__random32(state);
|
||||
__random32(state);
|
||||
__random32(state);
|
||||
__random32(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* random32 - pseudo random number generator
|
||||
*
|
||||
* A 32 bit pseudo-random number is generated using a fast
|
||||
* algorithm suitable for simulation. This algorithm is NOT
|
||||
* considered safe for cryptographic use.
|
||||
*/
|
||||
u32 random32(void)
|
||||
{
|
||||
return __random32(&net_rand_state[smp_processor_id()]);
|
||||
}
|
||||
EXPORT_SYMBOL(random32);
|
||||
|
||||
/**
|
||||
* srandom32 - add entropy to pseudo random number generator
|
||||
* @seed: seed value
|
||||
*
|
||||
* Add some additional seeding to the random32() pool.
|
||||
* Note: this pool is per cpu so it only affects current CPU.
|
||||
*/
|
||||
void srandom32(u32 entropy)
|
||||
{
|
||||
struct rnd_state *state = &net_rand_state[smp_processor_id()];
|
||||
__set_random32(state, state->s1 ^ entropy);
|
||||
}
|
||||
EXPORT_SYMBOL(srandom32);
|
||||
|
||||
static int __init random32_reseed(void);
|
||||
|
||||
/*
|
||||
* Generate some initially weak seeding values to allow
|
||||
* to start the random32() engine.
|
||||
*/
|
||||
int __init random32_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NR_CPUS; i++) {
|
||||
struct rnd_state *state = &net_rand_state[i];
|
||||
__set_random32(state, i + jiffies);
|
||||
}
|
||||
random32_reseed();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate better values after random number generator
|
||||
* is fully initalized.
|
||||
*/
|
||||
static int __init random32_reseed(void)
|
||||
{
|
||||
int i;
|
||||
unsigned long seed;
|
||||
|
||||
for (i = 0; i < NR_CPUS; i++) {
|
||||
struct rnd_state *state = &net_rand_state[i];
|
||||
|
||||
get_random_bytes(&seed, sizeof(seed));
|
||||
__set_random32(state, seed);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Distributed under the terms of the GNU GPL version 2.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/tqueue.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
#include "compat24.h"
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#error "SMP configurations not supported for RCU backport."
|
||||
#endif
|
||||
|
||||
static int default_blimit = 10;
|
||||
static int blimit;
|
||||
static int qhimark = 10000;
|
||||
static int qlowmark = 100;
|
||||
|
||||
static struct rcu_head *head, **tail;
|
||||
static int qlen = 0;
|
||||
|
||||
static struct tq_struct rcu_task;
|
||||
|
||||
/*
|
||||
* Invoke the completed RCU callbacks. They are expected to be in
|
||||
* a per-cpu list.
|
||||
*/
|
||||
static void rcu_task_routine(void *unused)
|
||||
{
|
||||
struct rcu_head *list, *next;
|
||||
int count = 0;
|
||||
|
||||
local_irq_disable();
|
||||
list = head;
|
||||
head = NULL;
|
||||
tail = &head;
|
||||
local_irq_enable();
|
||||
|
||||
while (list) {
|
||||
next = list->next;
|
||||
prefetch(next);
|
||||
list->func(list);
|
||||
list = next;
|
||||
if (++count >= blimit)
|
||||
break;
|
||||
}
|
||||
|
||||
local_irq_disable();
|
||||
qlen -= count;
|
||||
local_irq_enable();
|
||||
if (blimit == INT_MAX && qlen <= qlowmark)
|
||||
blimit = default_blimit;
|
||||
|
||||
if (head)
|
||||
schedule_task(&rcu_task);
|
||||
}
|
||||
|
||||
|
||||
static inline void force_quiescent_state(void)
|
||||
{
|
||||
current->need_resched = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* call_rcu - Queue an RCU callback for invocation after a grace period.
|
||||
* @rcu: structure to be used for queueing the RCU updates.
|
||||
* @func: actual update function to be invoked after the grace period
|
||||
*
|
||||
* The update function will be invoked some time after a full grace
|
||||
* period elapses, in other words after all currently executing RCU
|
||||
* read-side critical sections have completed. RCU read-side critical
|
||||
* sections are delimited by rcu_read_lock() and rcu_read_unlock(),
|
||||
* and may be nested.
|
||||
*/
|
||||
void call_rcu(struct rcu_head *rcu, void (*func)(struct rcu_head *rcu))
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* FIXME? Following may be mildly expensive, may be worthwhile to
|
||||
optimize common case. */
|
||||
schedule_task(&rcu_task);
|
||||
|
||||
rcu->func = func;
|
||||
rcu->next = NULL;
|
||||
local_irq_save(flags);
|
||||
*tail = rcu;
|
||||
tail = &rcu->next;
|
||||
if (unlikely(++qlen > qhimark)) {
|
||||
blimit = INT_MAX;
|
||||
force_quiescent_state();
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
EXPORT_SYMBOL(call_rcu);
|
||||
|
||||
void rcu_init(void)
|
||||
{
|
||||
head = NULL;
|
||||
tail = &head;
|
||||
blimit = default_blimit;
|
||||
rcu_task.routine = rcu_task_routine;
|
||||
}
|
||||
|
||||
struct rcu_synchronize {
|
||||
struct rcu_head head;
|
||||
struct completion completion;
|
||||
};
|
||||
|
||||
/* Because of FASTCALL declaration of complete, we use this wrapper */
|
||||
static void wakeme_after_rcu(struct rcu_head *head)
|
||||
{
|
||||
struct rcu_synchronize *rcu;
|
||||
|
||||
rcu = container_of(head, struct rcu_synchronize, head);
|
||||
complete(&rcu->completion);
|
||||
}
|
||||
|
||||
/**
|
||||
* synchronize_rcu - wait until a grace period has elapsed.
|
||||
*
|
||||
* Control will return to the caller some time after a full grace
|
||||
* period has elapsed, in other words after all currently executing RCU
|
||||
* read-side critical sections have completed. RCU read-side critical
|
||||
* sections are delimited by rcu_read_lock() and rcu_read_unlock(),
|
||||
* and may be nested.
|
||||
*
|
||||
* If your read-side code is not protected by rcu_read_lock(), do -not-
|
||||
* use synchronize_rcu().
|
||||
*/
|
||||
void synchronize_rcu(void)
|
||||
{
|
||||
struct rcu_synchronize rcu;
|
||||
|
||||
init_completion(&rcu.completion);
|
||||
/* Will wake me after RCU finished */
|
||||
call_rcu(&rcu.head, wakeme_after_rcu);
|
||||
|
||||
/* Wait for it */
|
||||
wait_for_completion(&rcu.completion);
|
||||
}
|
||||
EXPORT_SYMBOL(synchronize_rcu);
|
||||
@@ -1,44 +0,0 @@
|
||||
#include "linux/sched.h"
|
||||
|
||||
#include <linux/version.h>
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/**
|
||||
* set_cpus_allowed() - change a given task's processor affinity
|
||||
* @p: task to bind
|
||||
* @new_mask: bitmask of allowed processors
|
||||
*
|
||||
* Upon return, the task is running on a legal processor. Note the caller
|
||||
* must have a valid reference to the task: it must not exit() prematurely.
|
||||
* This call can sleep; do not hold locks on call.
|
||||
*/
|
||||
void set_cpus_allowed(struct task_struct *p, unsigned long new_mask)
|
||||
{
|
||||
new_mask &= cpu_online_map;
|
||||
BUG_ON(!new_mask);
|
||||
|
||||
p->cpus_allowed = new_mask;
|
||||
|
||||
/*
|
||||
* If the task is on a no-longer-allowed processor, we need to move
|
||||
* it. If the task is not current, then set need_resched and send
|
||||
* its processor an IPI to reschedule.
|
||||
*/
|
||||
if (!(p->cpus_runnable & p->cpus_allowed)) {
|
||||
if (p != current) {
|
||||
p->need_resched = 1;
|
||||
smp_send_reschedule(p->processor);
|
||||
}
|
||||
/*
|
||||
* Wait until we are on a legal processor. If the task is
|
||||
* current, then we should be on a legal processor the next
|
||||
* time we reschedule. Otherwise, we need to wait for the IPI.
|
||||
*/
|
||||
while (!(p->cpus_runnable & p->cpus_allowed))
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* kernel < 2.4.21 */
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Distributed under the terms of the GNU GPL version 2.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCSPN
|
||||
/**
|
||||
* strcspn - Calculate the length of the initial substring of @s which does not contain letters in @reject
|
||||
* @s: The string to be searched
|
||||
* @reject: The string to avoid
|
||||
*/
|
||||
size_t strcspn(const char *s, const char *reject)
|
||||
{
|
||||
const char *p;
|
||||
const char *r;
|
||||
size_t count = 0;
|
||||
|
||||
for (p = s; *p != '\0'; ++p) {
|
||||
for (r = reject; *r != '\0'; ++r) {
|
||||
if (*p == *r)
|
||||
return count;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
EXPORT_SYMBOL(strcspn);
|
||||
|
||||
/**
|
||||
* strlcpy - Copy a %NUL terminated string into a sized buffer
|
||||
* @dest: Where to copy the string to
|
||||
* @src: Where to copy the string from
|
||||
* @size: size of destination buffer
|
||||
*
|
||||
* Compatible with *BSD: the result is always a valid
|
||||
* NUL-terminated string that fits in the buffer (unless,
|
||||
* of course, the buffer size is zero). It does not pad
|
||||
* out the result like strncpy() does.
|
||||
*/
|
||||
size_t strlcpy(char *dest, const char *src, size_t size)
|
||||
{
|
||||
size_t ret = strlen(src);
|
||||
|
||||
if (size) {
|
||||
size_t len = (ret >= size) ? size - 1 : ret;
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(strlcpy);
|
||||
|
||||
#endif
|
||||
@@ -1,600 +0,0 @@
|
||||
#
|
||||
# Automatically generated make config: don't edit
|
||||
#
|
||||
CONFIG_X86=y
|
||||
# CONFIG_SBUS is not set
|
||||
CONFIG_UID16=y
|
||||
|
||||
#
|
||||
# Code maturity level options
|
||||
#
|
||||
# CONFIG_EXPERIMENTAL is not set
|
||||
|
||||
#
|
||||
# Loadable module support
|
||||
#
|
||||
CONFIG_MODULES=y
|
||||
CONFIG_MODVERSIONS=y
|
||||
CONFIG_KMOD=y
|
||||
|
||||
#
|
||||
# Processor type and features
|
||||
#
|
||||
# CONFIG_M386 is not set
|
||||
# CONFIG_M486 is not set
|
||||
# CONFIG_M586 is not set
|
||||
# CONFIG_M586TSC is not set
|
||||
# CONFIG_M586MMX is not set
|
||||
# CONFIG_M686 is not set
|
||||
CONFIG_MPENTIUMIII=y
|
||||
# CONFIG_MPENTIUM4 is not set
|
||||
# CONFIG_MK6 is not set
|
||||
# CONFIG_MK7 is not set
|
||||
# CONFIG_MK8 is not set
|
||||
# CONFIG_MELAN is not set
|
||||
# CONFIG_MCRUSOE is not set
|
||||
# CONFIG_MWINCHIPC6 is not set
|
||||
# CONFIG_MWINCHIP2 is not set
|
||||
# CONFIG_MWINCHIP3D is not set
|
||||
# CONFIG_MCYRIXIII is not set
|
||||
# CONFIG_MVIAC3_2 is not set
|
||||
CONFIG_X86_WP_WORKS_OK=y
|
||||
CONFIG_X86_INVLPG=y
|
||||
CONFIG_X86_CMPXCHG=y
|
||||
CONFIG_X86_XADD=y
|
||||
CONFIG_X86_BSWAP=y
|
||||
CONFIG_X86_POPAD_OK=y
|
||||
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
|
||||
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
|
||||
# CONFIG_X86_TSC is not set
|
||||
CONFIG_X86_L1_CACHE_SHIFT=5
|
||||
CONFIG_X86_HAS_TSC=y
|
||||
CONFIG_X86_GOOD_APIC=y
|
||||
CONFIG_X86_PGE=y
|
||||
CONFIG_X86_USE_PPRO_CHECKSUM=y
|
||||
CONFIG_X86_F00F_WORKS_OK=y
|
||||
# CONFIG_X86_MCE is not set
|
||||
# CONFIG_TOSHIBA is not set
|
||||
# CONFIG_I8K is not set
|
||||
# CONFIG_MICROCODE is not set
|
||||
# CONFIG_X86_MSR is not set
|
||||
# CONFIG_X86_CPUID is not set
|
||||
CONFIG_NOHIGHMEM=y
|
||||
# CONFIG_HIGHMEM4G is not set
|
||||
# CONFIG_HIGHMEM64G is not set
|
||||
# CONFIG_HIGHMEM is not set
|
||||
# CONFIG_MATH_EMULATION is not set
|
||||
# CONFIG_MTRR is not set
|
||||
# CONFIG_SMP is not set
|
||||
# CONFIG_X86_UP_APIC is not set
|
||||
# CONFIG_X86_TSC_DISABLE is not set
|
||||
CONFIG_X86_TSC=y
|
||||
|
||||
#
|
||||
# General setup
|
||||
#
|
||||
CONFIG_NET=y
|
||||
CONFIG_PCI=y
|
||||
# CONFIG_PCI_GOBIOS is not set
|
||||
# CONFIG_PCI_GODIRECT is not set
|
||||
CONFIG_PCI_GOANY=y
|
||||
CONFIG_PCI_BIOS=y
|
||||
CONFIG_PCI_DIRECT=y
|
||||
CONFIG_ISA=y
|
||||
CONFIG_PCI_NAMES=y
|
||||
# CONFIG_EISA is not set
|
||||
# CONFIG_MCA is not set
|
||||
# CONFIG_HOTPLUG is not set
|
||||
# CONFIG_PCMCIA is not set
|
||||
# CONFIG_HOTPLUG_PCI is not set
|
||||
CONFIG_SYSVIPC=y
|
||||
# CONFIG_BSD_PROCESS_ACCT is not set
|
||||
CONFIG_SYSCTL=y
|
||||
CONFIG_KCORE_ELF=y
|
||||
# CONFIG_KCORE_AOUT is not set
|
||||
CONFIG_BINFMT_AOUT=y
|
||||
CONFIG_BINFMT_ELF=y
|
||||
CONFIG_BINFMT_MISC=y
|
||||
# CONFIG_OOM_KILLER is not set
|
||||
CONFIG_PM=y
|
||||
# CONFIG_APM is not set
|
||||
|
||||
#
|
||||
# ACPI Support
|
||||
#
|
||||
# CONFIG_ACPI is not set
|
||||
|
||||
#
|
||||
# Memory Technology Devices (MTD)
|
||||
#
|
||||
# CONFIG_MTD is not set
|
||||
|
||||
#
|
||||
# Parallel port support
|
||||
#
|
||||
# CONFIG_PARPORT is not set
|
||||
|
||||
#
|
||||
# Plug and Play configuration
|
||||
#
|
||||
# CONFIG_PNP is not set
|
||||
|
||||
#
|
||||
# Block devices
|
||||
#
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
# CONFIG_BLK_DEV_XD 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_SX8 is not set
|
||||
# CONFIG_BLK_DEV_LOOP is not set
|
||||
# CONFIG_BLK_DEV_NBD is not set
|
||||
# CONFIG_BLK_DEV_RAM is not set
|
||||
# CONFIG_BLK_STATS is not set
|
||||
|
||||
#
|
||||
# Multi-device support (RAID and LVM)
|
||||
#
|
||||
# CONFIG_MD is not set
|
||||
|
||||
#
|
||||
# Networking options
|
||||
#
|
||||
CONFIG_PACKET=y
|
||||
# CONFIG_PACKET_MMAP is not set
|
||||
# CONFIG_NETLINK_DEV is not set
|
||||
# CONFIG_NETFILTER is not set
|
||||
CONFIG_FILTER=y
|
||||
CONFIG_UNIX=y
|
||||
CONFIG_INET=y
|
||||
CONFIG_IP_MULTICAST=y
|
||||
# CONFIG_IP_ADVANCED_ROUTER is not set
|
||||
# CONFIG_IP_PNP is not set
|
||||
# CONFIG_NET_IPIP is not set
|
||||
# CONFIG_NET_IPGRE is not set
|
||||
# CONFIG_IP_MROUTE is not set
|
||||
# CONFIG_INET_ECN is not set
|
||||
# CONFIG_SYN_COOKIES is not set
|
||||
# CONFIG_VLAN_8021Q is not set
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
# CONFIG_IPX is not set
|
||||
# CONFIG_ATALK is not set
|
||||
# CONFIG_DECNET is not set
|
||||
CONFIG_BRIDGE=y
|
||||
|
||||
#
|
||||
# QoS and/or fair queueing
|
||||
#
|
||||
# CONFIG_NET_SCHED is not set
|
||||
|
||||
#
|
||||
# Network testing
|
||||
#
|
||||
# CONFIG_NET_PKTGEN is not set
|
||||
|
||||
#
|
||||
# Telephony Support
|
||||
#
|
||||
# CONFIG_PHONE is not set
|
||||
|
||||
#
|
||||
# ATA/IDE/MFM/RLL support
|
||||
#
|
||||
CONFIG_IDE=y
|
||||
|
||||
#
|
||||
# IDE, ATA and ATAPI Block devices
|
||||
#
|
||||
CONFIG_BLK_DEV_IDE=y
|
||||
|
||||
#
|
||||
# Please see Documentation/ide.txt for help/info on IDE drives
|
||||
#
|
||||
# CONFIG_BLK_DEV_HD_IDE is not set
|
||||
# CONFIG_BLK_DEV_HD is not set
|
||||
# CONFIG_BLK_DEV_IDE_SATA is not set
|
||||
CONFIG_BLK_DEV_IDEDISK=y
|
||||
CONFIG_IDEDISK_MULTI_MODE=y
|
||||
# CONFIG_IDEDISK_STROKE is not set
|
||||
CONFIG_BLK_DEV_IDECD=y
|
||||
# CONFIG_BLK_DEV_IDETAPE is not set
|
||||
# CONFIG_BLK_DEV_IDEFLOPPY is not set
|
||||
# CONFIG_IDE_TASK_IOCTL is not set
|
||||
|
||||
#
|
||||
# IDE chipset support/bugfixes
|
||||
#
|
||||
# CONFIG_BLK_DEV_CMD640 is not set
|
||||
CONFIG_BLK_DEV_IDEPCI=y
|
||||
# CONFIG_BLK_DEV_GENERIC is not set
|
||||
CONFIG_IDEPCI_SHARE_IRQ=y
|
||||
CONFIG_BLK_DEV_IDEDMA_PCI=y
|
||||
# CONFIG_BLK_DEV_OFFBOARD is not set
|
||||
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
|
||||
CONFIG_IDEDMA_PCI_AUTO=y
|
||||
# CONFIG_IDEDMA_ONLYDISK is not set
|
||||
CONFIG_BLK_DEV_IDEDMA=y
|
||||
# CONFIG_BLK_DEV_ADMA100 is not set
|
||||
# CONFIG_BLK_DEV_AEC62XX is not set
|
||||
# CONFIG_BLK_DEV_ALI15X3 is not set
|
||||
# CONFIG_BLK_DEV_AMD74XX is not set
|
||||
# CONFIG_BLK_DEV_ATIIXP is not set
|
||||
# CONFIG_BLK_DEV_CMD64X is not set
|
||||
# CONFIG_BLK_DEV_TRIFLEX is not set
|
||||
# CONFIG_BLK_DEV_CY82C693 is not set
|
||||
# CONFIG_BLK_DEV_CS5530 is not set
|
||||
# CONFIG_BLK_DEV_HPT34X is not set
|
||||
# CONFIG_BLK_DEV_HPT366 is not set
|
||||
CONFIG_BLK_DEV_PIIX=y
|
||||
# CONFIG_BLK_DEV_NS87415 is not set
|
||||
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
|
||||
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
|
||||
CONFIG_BLK_DEV_RZ1000=y
|
||||
# CONFIG_BLK_DEV_SC1200 is not set
|
||||
# CONFIG_BLK_DEV_SVWKS is not set
|
||||
# CONFIG_BLK_DEV_SIIMAGE is not set
|
||||
# CONFIG_BLK_DEV_SIS5513 is not set
|
||||
# CONFIG_BLK_DEV_SLC90E66 is not set
|
||||
# CONFIG_BLK_DEV_TRM290 is not set
|
||||
# CONFIG_BLK_DEV_VIA82CXXX is not set
|
||||
# CONFIG_IDE_CHIPSETS is not set
|
||||
CONFIG_IDEDMA_AUTO=y
|
||||
# CONFIG_IDEDMA_IVB is not set
|
||||
# CONFIG_DMA_NONPCI is not set
|
||||
|
||||
#
|
||||
# SCSI support
|
||||
#
|
||||
# CONFIG_SCSI is not set
|
||||
|
||||
#
|
||||
# Fusion MPT device support
|
||||
#
|
||||
# CONFIG_FUSION_BOOT is not set
|
||||
# CONFIG_FUSION_ISENSE is not set
|
||||
# CONFIG_FUSION_CTL is not set
|
||||
# CONFIG_FUSION_LAN is not set
|
||||
|
||||
#
|
||||
# I2O device support
|
||||
#
|
||||
# CONFIG_I2O is not set
|
||||
|
||||
#
|
||||
# Network device support
|
||||
#
|
||||
CONFIG_NETDEVICES=y
|
||||
|
||||
#
|
||||
# ARCnet devices
|
||||
#
|
||||
# CONFIG_ARCNET is not set
|
||||
CONFIG_DUMMY=m
|
||||
# CONFIG_BONDING is not set
|
||||
# CONFIG_EQUALIZER is not set
|
||||
# CONFIG_TUN is not set
|
||||
|
||||
#
|
||||
# Ethernet (10 or 100Mbit)
|
||||
#
|
||||
CONFIG_NET_ETHERNET=y
|
||||
# CONFIG_HAPPYMEAL is not set
|
||||
# CONFIG_SUNGEM is not set
|
||||
# CONFIG_NET_VENDOR_3COM is not set
|
||||
# CONFIG_LANCE is not set
|
||||
# CONFIG_NET_VENDOR_SMC is not set
|
||||
# CONFIG_NET_VENDOR_RACAL is not set
|
||||
# CONFIG_DEPCA is not set
|
||||
# CONFIG_HP100 is not set
|
||||
# CONFIG_NET_ISA 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_APRICOT is not set
|
||||
# CONFIG_CS89x0 is not set
|
||||
# CONFIG_TULIP is not set
|
||||
# CONFIG_DE4X5 is not set
|
||||
# CONFIG_DGRS is not set
|
||||
# CONFIG_DM9102 is not set
|
||||
CONFIG_EEPRO100=y
|
||||
# CONFIG_EEPRO100_PIO is not set
|
||||
# CONFIG_E100 is not set
|
||||
# CONFIG_FEALNX is not set
|
||||
# CONFIG_NATSEMI is not set
|
||||
CONFIG_NE2K_PCI=y
|
||||
CONFIG_8139TOO=y
|
||||
# CONFIG_8139TOO_PIO is not set
|
||||
# CONFIG_8139TOO_TUNE_TWISTER is not set
|
||||
# CONFIG_8139TOO_8129 is not set
|
||||
# CONFIG_8139_OLD_RX_RESET 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
|
||||
# CONFIG_WINBOND_840 is not set
|
||||
# CONFIG_NET_POCKET 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_R8169 is not set
|
||||
# CONFIG_SKGE is not set
|
||||
# CONFIG_SKY2 is not set
|
||||
# CONFIG_SK98LIN is not set
|
||||
# CONFIG_TIGON3 is not set
|
||||
# CONFIG_FDDI is not set
|
||||
# CONFIG_PPP is not set
|
||||
# CONFIG_SLIP is not set
|
||||
|
||||
#
|
||||
# Wireless LAN (non-hamradio)
|
||||
#
|
||||
# CONFIG_NET_RADIO is not set
|
||||
|
||||
#
|
||||
# Token Ring devices
|
||||
#
|
||||
# CONFIG_TR is not set
|
||||
# CONFIG_NET_FC is not set
|
||||
|
||||
#
|
||||
# Wan interfaces
|
||||
#
|
||||
# CONFIG_WAN is not set
|
||||
|
||||
#
|
||||
# Amateur Radio support
|
||||
#
|
||||
# CONFIG_HAMRADIO is not set
|
||||
|
||||
#
|
||||
# IrDA (infrared) support
|
||||
#
|
||||
# CONFIG_IRDA is not set
|
||||
|
||||
#
|
||||
# ISDN subsystem
|
||||
#
|
||||
# CONFIG_ISDN is not set
|
||||
|
||||
#
|
||||
# Old CD-ROM drivers (not SCSI, not IDE)
|
||||
#
|
||||
# CONFIG_CD_NO_IDESCSI is not set
|
||||
|
||||
#
|
||||
# Input core support
|
||||
#
|
||||
# CONFIG_INPUT is not set
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
|
||||
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
|
||||
|
||||
#
|
||||
# Character devices
|
||||
#
|
||||
CONFIG_VT=y
|
||||
CONFIG_VT_CONSOLE=y
|
||||
CONFIG_SERIAL=y
|
||||
CONFIG_SERIAL_CONSOLE=y
|
||||
# CONFIG_SERIAL_EXTENDED is not set
|
||||
# CONFIG_SERIAL_NONSTANDARD is not set
|
||||
CONFIG_UNIX98_PTYS=y
|
||||
CONFIG_UNIX98_PTY_COUNT=256
|
||||
|
||||
#
|
||||
# I2C support
|
||||
#
|
||||
# CONFIG_I2C is not set
|
||||
|
||||
#
|
||||
# Mice
|
||||
#
|
||||
# CONFIG_BUSMOUSE is not set
|
||||
CONFIG_MOUSE=y
|
||||
CONFIG_PSMOUSE=y
|
||||
# CONFIG_82C710_MOUSE is not set
|
||||
# CONFIG_PC110_PAD is not set
|
||||
# CONFIG_MK712_MOUSE is not set
|
||||
|
||||
#
|
||||
# Joysticks
|
||||
#
|
||||
# CONFIG_INPUT_GAMEPORT is not set
|
||||
|
||||
#
|
||||
# Input core support is needed for gameports
|
||||
#
|
||||
|
||||
#
|
||||
# Input core support is needed for joysticks
|
||||
#
|
||||
# CONFIG_QIC02_TAPE is not set
|
||||
# CONFIG_IPMI_HANDLER is not set
|
||||
|
||||
#
|
||||
# Watchdog Cards
|
||||
#
|
||||
# CONFIG_WATCHDOG is not set
|
||||
# CONFIG_SCx200 is not set
|
||||
# CONFIG_AMD_RNG is not set
|
||||
# CONFIG_INTEL_RNG is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_AMD_PM768 is not set
|
||||
# CONFIG_NVRAM is not set
|
||||
# CONFIG_RTC 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_FTAPE is not set
|
||||
# CONFIG_AGP is not set
|
||||
|
||||
#
|
||||
# Direct Rendering Manager (XFree86 DRI support)
|
||||
#
|
||||
# CONFIG_DRM is not set
|
||||
# CONFIG_MWAVE is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
|
||||
#
|
||||
# File systems
|
||||
#
|
||||
# CONFIG_QUOTA is not set
|
||||
# CONFIG_AUTOFS_FS is not set
|
||||
# CONFIG_AUTOFS4_FS is not set
|
||||
# CONFIG_REISERFS_FS is not set
|
||||
CONFIG_EXT3_FS=y
|
||||
CONFIG_JBD=y
|
||||
# CONFIG_JBD_DEBUG is not set
|
||||
# CONFIG_FAT_FS is not set
|
||||
# CONFIG_CRAMFS is not set
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_RAMFS=y
|
||||
CONFIG_ISO9660_FS=y
|
||||
# CONFIG_JOLIET is not set
|
||||
# CONFIG_ZISOFS is not set
|
||||
# CONFIG_JFS_FS is not set
|
||||
# CONFIG_MINIX_FS is not set
|
||||
# CONFIG_VXFS_FS is not set
|
||||
# CONFIG_NTFS_FS is not set
|
||||
# CONFIG_HPFS_FS is not set
|
||||
CONFIG_PROC_FS=y
|
||||
CONFIG_DEVPTS_FS=y
|
||||
# CONFIG_QNX4FS_FS is not set
|
||||
# CONFIG_ROMFS_FS is not set
|
||||
# CONFIG_EXT2_FS is not set
|
||||
# CONFIG_SYSV_FS is not set
|
||||
# CONFIG_UDF_FS is not set
|
||||
# CONFIG_UFS_FS is not set
|
||||
# CONFIG_XFS_FS is not set
|
||||
|
||||
#
|
||||
# Network File Systems
|
||||
#
|
||||
# CONFIG_CODA_FS is not set
|
||||
# CONFIG_NFS_FS is not set
|
||||
# CONFIG_NFSD is not set
|
||||
# CONFIG_SUNRPC is not set
|
||||
# CONFIG_LOCKD is not set
|
||||
# CONFIG_SMB_FS is not set
|
||||
# CONFIG_NCP_FS is not set
|
||||
# CONFIG_ZISOFS_FS is not set
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
#
|
||||
# CONFIG_PARTITION_ADVANCED is not set
|
||||
CONFIG_MSDOS_PARTITION=y
|
||||
# CONFIG_SMB_NLS is not set
|
||||
CONFIG_NLS=y
|
||||
|
||||
#
|
||||
# Native Language Support
|
||||
#
|
||||
CONFIG_NLS_DEFAULT="iso8859-1"
|
||||
# CONFIG_NLS_CODEPAGE_437 is not set
|
||||
# CONFIG_NLS_CODEPAGE_737 is not set
|
||||
# CONFIG_NLS_CODEPAGE_775 is not set
|
||||
# CONFIG_NLS_CODEPAGE_850 is not set
|
||||
# CONFIG_NLS_CODEPAGE_852 is not set
|
||||
# CONFIG_NLS_CODEPAGE_855 is not set
|
||||
# CONFIG_NLS_CODEPAGE_857 is not set
|
||||
# CONFIG_NLS_CODEPAGE_860 is not set
|
||||
# CONFIG_NLS_CODEPAGE_861 is not set
|
||||
# CONFIG_NLS_CODEPAGE_862 is not set
|
||||
# CONFIG_NLS_CODEPAGE_863 is not set
|
||||
# CONFIG_NLS_CODEPAGE_864 is not set
|
||||
# CONFIG_NLS_CODEPAGE_865 is not set
|
||||
# CONFIG_NLS_CODEPAGE_866 is not set
|
||||
# CONFIG_NLS_CODEPAGE_869 is not set
|
||||
# CONFIG_NLS_CODEPAGE_936 is not set
|
||||
# CONFIG_NLS_CODEPAGE_950 is not set
|
||||
# CONFIG_NLS_CODEPAGE_932 is not set
|
||||
# CONFIG_NLS_CODEPAGE_949 is not set
|
||||
# CONFIG_NLS_CODEPAGE_874 is not set
|
||||
# CONFIG_NLS_ISO8859_8 is not set
|
||||
# CONFIG_NLS_CODEPAGE_1250 is not set
|
||||
# CONFIG_NLS_CODEPAGE_1251 is not set
|
||||
# CONFIG_NLS_ISO8859_1 is not set
|
||||
# CONFIG_NLS_ISO8859_2 is not set
|
||||
# CONFIG_NLS_ISO8859_3 is not set
|
||||
# CONFIG_NLS_ISO8859_4 is not set
|
||||
# CONFIG_NLS_ISO8859_5 is not set
|
||||
# CONFIG_NLS_ISO8859_6 is not set
|
||||
# CONFIG_NLS_ISO8859_7 is not set
|
||||
# CONFIG_NLS_ISO8859_9 is not set
|
||||
# CONFIG_NLS_ISO8859_13 is not set
|
||||
# CONFIG_NLS_ISO8859_14 is not set
|
||||
# CONFIG_NLS_ISO8859_15 is not set
|
||||
# CONFIG_NLS_KOI8_R is not set
|
||||
# CONFIG_NLS_KOI8_U is not set
|
||||
# CONFIG_NLS_UTF8 is not set
|
||||
|
||||
#
|
||||
# Console drivers
|
||||
#
|
||||
CONFIG_VGA_CONSOLE=y
|
||||
# CONFIG_VIDEO_SELECT is not set
|
||||
|
||||
#
|
||||
# Sound
|
||||
#
|
||||
# CONFIG_SOUND is not set
|
||||
|
||||
#
|
||||
# USB support
|
||||
#
|
||||
# CONFIG_USB is not set
|
||||
|
||||
#
|
||||
# Support for USB gadgets
|
||||
#
|
||||
# CONFIG_USB_GADGET is not set
|
||||
|
||||
#
|
||||
# Bluetooth support
|
||||
#
|
||||
# CONFIG_BLUEZ is not set
|
||||
|
||||
#
|
||||
# Kernel hacking
|
||||
#
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
# CONFIG_DEBUG_STACKOVERFLOW is not set
|
||||
# CONFIG_DEBUG_HIGHMEM is not set
|
||||
# CONFIG_DEBUG_SLAB is not set
|
||||
# CONFIG_DEBUG_IOVIRT is not set
|
||||
# CONFIG_MAGIC_SYSRQ is not set
|
||||
# CONFIG_DEBUG_SPINLOCK is not set
|
||||
CONFIG_FRAME_POINTER=y
|
||||
CONFIG_LOG_BUF_SHIFT=0
|
||||
|
||||
#
|
||||
# Cryptographic options
|
||||
#
|
||||
# CONFIG_CRYPTO is not set
|
||||
|
||||
#
|
||||
# Library routines
|
||||
#
|
||||
CONFIG_CRC32=y
|
||||
# CONFIG_ZLIB_INFLATE is not set
|
||||
# CONFIG_ZLIB_DEFLATE is not set
|
||||
Reference in new issue
Block a user