[PATCH 1/2] myri10ge - Write the firmware in 256-bytes chunks
When writing the firmware to the NIC, the FIFO is 256-bytes long, so we use 256-bytes chunks and a read to wait until the previous write is done. Signed-off-by: Brice Goglin <[EMAIL PROTECTED]> --- drivers/net/myri10ge/myri10ge.c | 19 +++ 1 file changed, 7 insertions(+), 12 deletions(-) Index: linux-mm/drivers/net/myri10ge/myri10ge.c === --- linux-mm.orig/drivers/net/myri10ge/myri10ge.c 2006-07-27 06:49:18.0 -0400 +++ linux-mm/drivers/net/myri10ge/myri10ge.c2006-07-29 10:02:39.0 -0400 @@ -448,6 +448,7 @@ struct mcp_gen_header *hdr; size_t hdr_offset; int status; + unsigned i; if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) { dev_err(dev, "Unable to load %s firmware image via hotplug\n", @@ -479,18 +480,12 @@ goto abort_with_fw; crc = crc32(~0, fw->data, fw->size); - if (mgp->tx.boundary == 2048) { - /* Avoid PCI burst on chipset with unaligned completions. */ - int i; - __iomem u32 *ptr = (__iomem u32 *) (mgp->sram + - MYRI10GE_FW_OFFSET); - for (i = 0; i < fw->size / 4; i++) { - __raw_writel(((u32 *) fw->data)[i], ptr + i); - wmb(); - } - } else { - myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET, fw->data, - fw->size); + for (i = 0; i < fw->size; i += 256) { + myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET + i, + fw->data + i, + min(256U, (unsigned)(fw->size - i))); + mb(); + readb(mgp->sram); } /* corruption checking is good for parity recovery and buggy chipset */ memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] myri10ge - Fix spurious invokations of the watchdog reset handler
Fix spurious invocations of the watchdog reset handler. Signed-off-by: Brice Goglin <[EMAIL PROTECTED]> --- drivers/net/myri10ge/myri10ge.c |5 - 1 file changed, 4 insertions(+), 1 deletion(-) Index: linux-mm/drivers/net/myri10ge/myri10ge.c === --- linux-mm.orig/drivers/net/myri10ge/myri10ge.c 2006-07-27 06:49:19.0 -0400 +++ linux-mm/drivers/net/myri10ge/myri10ge.c2006-07-27 15:34:02.0 -0400 @@ -177,6 +177,7 @@ struct work_struct watchdog_work; struct timer_list watchdog_timer; int watchdog_tx_done; + int watchdog_tx_req; int watchdog_resets; int tx_linearized; int pause; @@ -2536,7 +2537,8 @@ mgp = (struct myri10ge_priv *)arg; if (mgp->tx.req != mgp->tx.done && - mgp->tx.done == mgp->watchdog_tx_done) + mgp->tx.done == mgp->watchdog_tx_done && + mgp->watchdog_tx_req != mgp->watchdog_tx_done) /* nic seems like it might be stuck.. */ schedule_work(&mgp->watchdog_work); else @@ -2545,6 +2547,7 @@ jiffies + myri10ge_watchdog_timeout * HZ); mgp->watchdog_tx_done = mgp->tx.done; + mgp->watchdog_tx_req = mgp->tx.req; } static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] myri10ge fixes
Hi, The following 2 patches fix the following issues in the myri10ge driver: #1 - When writing the firmware to the NIC, the FIFO is 256-bytes long, so we use 256-bytes chunks and a read to wait until the previous write is done. I sent this patch two weeks ago, this new version removes the superfluous second mb(). #2 - Fix spurious invocations of the watchdog reset handler. Please apply, Thanks, Brice Goglin - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Regarding offloading IPv6 addrconf and ndisc
Hi Hugo, I think it is not correct to refer the IPSec architecture in the context. It is originally desigened to separete the packet processing and the management. They are loosely coupled and are not always synchronized. For example if the daemon installs a pair of SAs which override the SAs in SAD, there is no problem and the IPsec stack uses new SAs. On the other hand, if a ND daemon loose the synchronization, it is unpredicable, I guess. BTW, we have a choice which we implement a functionality as a module. I think it can achieve some of what you want. Regards, Hugo Santos wrote: > Hi Jamal, > >Through this discussion i've identified three points: one is that > some believe control and data should be kept synchronized; the other is > how some (including all of the first :-) think control should remain > inside the kernel; and finally you and me so far who believe they > should be separated for increased flexibility. If we consider the first > point, i would too have difficulties accepting the second one, taking > the same considerations Stephen mentioned, where an application could > possibly bork the kernel. So, first of all, we need to settle whether > data really needs to be in-sync with control (already assuming the > complexity control is gaining). > >Personally i think the answer is clear; the overall throughput > depends on the amount of time spent in a single state. Thus, the data > path should be well contained and depend only on the current state; > while control executes in parallel as it's state transitions are much > longer and might depend on multiple sub-transitions (communicating with > peers, etc). > >Deciding whether control should remain inside the kernel or not is > another story; as you point out, people generically don't like to > depend on daemons. I understand this point, and i think a solution that > would keep both parties happy would be to have the current > functionality inside the kernel while at the same time allowing control > daemons to take over and support additional complex features. > >I would say that the generic worries such as 'how do we handle out of > memory', or 'what if it crashes' or even 'what if it is overloaded' > apply both to the kernel and to a possible user-space application. > >- As this control daemon is important for the proper interaction of > the host with the network, we would reduce it's chances of being > OOM killed (while at the same time implementing algorithms to > prevent DoS by state flooding); >- Regarding the crashes, i think it is better for a system to have an > application rather than a kernel component crash as it might be > seamlessly restarted to recover. I would also say that the complex- > ity of the code is the same (or worst if in the kernel) to support > exactly the same features; >- The overloading problem also applies to the kernel, and would be > something that must be considered by either implementation; > >Don't forget that having this functionality in a daemon would also > allow for easier updates (including updates without having to reboot > your machine) besides offering a greater degree of flexibility. > >Let me also point out to any IKE daemon, where the SA/SP database is > kept in kernel, but is provided for by the daemon using explicit > requests by the kernel (ACQUIREs). If we consider neighbor discovery > for instance, if configured to do so, and as an example, instead of > sending an IPv6 NS, the kernel could netlink broadcast (or unicast to a > specific controller) the request due to an entry being STALEd and being > required where the daemon would then update the entry to REACHABLE. > >I'm sure some of you will continue to disagree, but i would really > like to move this decision to the user (or system deployer). > >Hugo -- Kazunori Miyazawa - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
What's new in wireless-dev?
Lots of patches lately, and I got a bit behind w/ travel to Ottawa and some "real job" stuff too... :-( I've still got a bunch of rt2x00 patches from Ivo, and a few other patches as well. Coming soon... John --- The following changes since commit 44ba187488edb4e567a0163d334f2bc0318dc392: John W. Linville: Merge branch 'from-linus' are found in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-dev.git Ivo van Doorn: rt2x00 makefile Jiri Benc: d80211: do not receive through master interface when not scanning d80211: host_gen_beacon_template flag d80211: better deallocation of mdev d80211: fix receiving through virtual interfaces d80211: fix defragmentation d80211: optimize defragmentation d80211: SET_NETDEV_DEV for non-master devices bcm43xx-d80211: use host_gen_beacon_template bcm43xx-d80211: use SET_NETDEV_DEV John W. Linville: Merge branch 'up' of git://git.kernel.org/.../jbenc/dscape Merge branch 'bcm43xx' of git://git.kernel.org/.../jbenc/dscape Larry Finger: bcm43xx: remove unused routines Michael Buesch: bcm43xx-d80211: Lower mac_suspend timeout bcm43xx-d80211: opencoded locking bcm43xx-d80211: init routine rewrite Michael Wu: d80211: Replace rc4 code with crypto api arc4 d80211: Add sparse bitwise annotations adm8211: Properly initialize priv->mode in adm8211_probe adm8211: Restore frame header after TX adm8211: Add MAINTAINERS entry Consolidate patch attached as wireless-dev.patch.bz2. -- John W. Linville [EMAIL PROTECTED] wireless-dev.patch.bz2 Description: BZip2 compressed data
Re: [parisc-linux] [git patches] tulip fixes from parisc-linux
On Sat, Jul 29, 2006 at 06:54:59PM -0400, Kyle McMartin wrote: > Hi Val, > > Sorry it took so long for me to get around to splitting > up the changes from the parisc-linux tree. But here > they finally are. Kyle, dude, you rock! Many thanks for doing that. I just wanted to warn that some of the changes are already in akpm 's tree (-mm). Becuase off hand I've forgotten which ones, would it be better to diff against -mm instead? thanks, grant - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [-mm patch] security/selinux/hooks.c: make 4 functions static
On Sat, 29 Jul 2006, Adrian Bunk wrote: > On Thu, Jul 27, 2006 at 01:56:39AM -0700, Andrew Morton wrote: > >... > > Changes since 2.6.18-rc2-mm1: > >... > > git-net.patch > >... > > git trees > >... > > This patch makes four needlessly global functions static. > > Signed-off-by: Adrian Bunk <[EMAIL PROTECTED]> Acked-by: James Morris <[EMAIL PROTECTED]> -- James Morris <[EMAIL PROTECTED]> - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[git patches] tulip fixes from parisc-linux
Hi Val, Sorry it took so long for me to get around to splitting up the changes from the parisc-linux tree. But here they finally are. This patchset has been running on a variety of parisc and ia64 machines for quite some time (several years...) without issue. Some of these are more cosmetic changes than anything else. Cheers, Kyle M. The following changes since commit dc710afe95ee9b263ab593c11d86a684f1606872: Linus Torvalds: Merge branch 'upstream-linus' of master.kernel.org:/.../jgarzik/libata-dev are found in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/kyle/tulip-2.6.git Francois Romieu: [TULIP] Defer tulip_select_media() to process context Grant Grundler: [TULIP] Fix PHY init and reset [TULIP] Print physical address in tulip_init_one [TULIP] Make tulip_stop_rxtx() failure case slightly more informative [TULIP] Clean tulip.h so it can be used by winbond-840.c [TULIP] Flush MMIO writes in reset sequence [TULIP] Fix IRQ/DMA race Helge Deller: [TULIP] Fix section mismatch in de2104x.c Thibaut Varene: [TULIP] Make DS21143 printout match lspci output drivers/net/tulip/21142.c |4 +- drivers/net/tulip/de2104x.c |6 +- drivers/net/tulip/interrupt.c |4 ++ drivers/net/tulip/media.c | 40 ++- drivers/net/tulip/timer.c | 14 + drivers/net/tulip/tulip.h | 43 drivers/net/tulip/tulip_core.c | 102 +++ drivers/net/tulip/winbond-840.c | 68 +- 8 files changed, 164 insertions(+), 117 deletions(-) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[DSCAPE] rate_control needs some form of reference counting
Hi, I'm getting reproductible oops when removing rt2500pci module (which uses devicescape ieee802.11 stack): # modprobe rt2500pci Loading module: rt2500pci - CVS (N/A) by http://rt2x00.serialmonkey.com. ACPI: PCI Interrupt :03:00.0[A] -> GSI 21 (level, low) -> IRQ 18 wmaster0: Failed to select rate control algorithm wmaster0: Failed to initialize rate control algorithm # lsmod Module Size Used by rt2500pci 29316 0 80211 137096 1 rt2500pci ipv6 206752 12 Note that rate_control isn't loaded. # rmmod rt2500pci Unloading module: rt2500pci - CVS (N/A) by http://rt2x00.serialmonkey.com. [ cut here ] kernel BUG at :46863! invalid opcode: [#1] SMP Modules linked in: rt2500pci 80211 ipv6 CPU:1 EIP:0060:[netdev_release+15/30]Not tainted VLI EFLAGS: 00010297 (2.6.17-riddly7.0 #1) EIP is at netdev_release+0xf/0x1e eax: d600c2e8 ebx: d600c2e8 ecx: c01ffb73 edx: d600c000 esi: c030b5c0 edi: d600c2f0 ebp: c030b5dc esp: d4e37ea8 ds: 007b es: 007b ss: 0068 Process rmmod (pid: 2306, threadinfo=d4e37000 task=c14f95b0) Stack: c01ffb3b d600c2f0 c03031f0 c0303220 c01b3139 d600c308 c01b3159 d600c000 c149f048 c01b377e d600c58c c01b3159 c01b377e d600c574 d600c400 c01b30de d600c2f0 e08e3f4f d600c400 d600c000 e08e3090 d67f9000 d67f989c e08d9e29 Call Trace: class_dev_release+0x2f/0x67 kobject_cleanup+0x40/0x60 kobject_release+0x0/0x8 kref_put+0x63/0x6d kobject_release+0x0/0x8 kref_put+0x63/0x6d kobject_unregister+0x14/0x1c ieee80211_sysfs_remove_netdevice+0x17/0x2e [80211] __ieee80211_if_del+0x2c/0x35 [80211] ieee80211_unregister_hw+0xa3/0x147 [80211] rt2500pci_remove+0x32/0x55 [rt2500pci] pci_device_remove+0x16/0x28 __device_release_driver+0x5a/0x72 driver_detach+0x5e/0x8b bus_remove_driver+0x27/0x41 driver_unregister+0xb/0x13 pci_unregister_driver+0xb/0x13 sys_delete_module+0x10d/0x132 do_munmap+0xda/0xe7 sysenter_past_esp+0x54/0x75 Code: 01 00 00 00 39 f8 7c 07 b8 f4 ff ff ff eb 09 c7 46 04 00 00 00 00 31 c0 5b 5e 5f c3 8d 90 18 fd ff ff 83 ba 94 02 00 00 04 74 02 <0f> 0b 0f b7 42 64 29 c2 89 d0 e9 c1 4a ef ff 05 e8 02 00 00 e9 EIP: [netdev_release+15/30] netdev_release+0xf/0x1e SS:ESP 0068:d4e37ea8 Loading rate_control before rt2500 pci "fixes" the problem. It isn't real fix but just hack -- driver uses rate_control module (indirectly via dscape) but I can unload it (rate_control) while it's running. I'm _guessing_ that rate_control needs its own set of kobjects and do some kobject_put/kobject_get in appropriate places... thanks -- This signature intentionally says nothing. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/7] NetLabel: core network changes
On Saturday 29 July 2006 12:34 pm, Venkat Yekkirala wrote: > > > This is only true wart I see in the patch set from my > > > perspective. > > > > > > You have security_post_accept_hook(), which gets the parent and > > > the child socket which is all the information you need, and it > > > seems to be invoked at the correct location. > > > > > > So can you please hook into this location using the security > > > level hook we already have? Just check sock->sk->sk_family is > > > PF_INET at the top of that hook if you only want to handle > > > ipv4 sockets, or something like that. > > > > > > Could this work? > > > > > > When preparing and argument stating why this won't work, please > > > suggest a nicer name for this af_inet.c hook or some way to make > > > it more generic and palatable to us. > > > > The only reason for having this new hook in inet_accept() is to catch > > all the in-kernel "daemons" who do not go through the LSM hooked > > accept() code path. I debated putting this hook into the patchset and > > in the end figured it was at least worth a shot. > > If I understand the patch correctly, the openreq inherits cipso from > the incoming syn and the syn-ack is then sent with this option. I further > see that the child sock inherits options from the openreq already. > > Could you then please elaborate on the need for explicitly copying options > from parent to child? The NetLabel patch allows administrators to assign specific a CIPSO DOI/configuration to each LSM "domain". Blindly using the CIPSO tag that the remote host sends could violate the administrator's NetLabel configuration. The current patch reads the CIPSO tag off the child socket, translating the tag according to the CIPSO DOI configuration to arrive at the correct/desired LSM security attributes. These LSM security attributes and the "domain" are then used to set the NetLabel on the socket. In the case where everyone is well behaved this should have no effect on the socket IP options and the packets sent across the wire. However, in the case of a not-nice remote host the outgoing CIPSO tag may change to match the administrators desired settings. It is important to note that the next patchset will be based against David's net-2.6.19 git tree which has the additional LSM hooks in the accept code path - which I plan to use - so expect the implementation to change as a result. Like I said earlier, these new LSM hooks are probably the proper way to do it, but I wanted to stick with the hooks that were present at the time I started working on NetLabel to minimize the impact on the kernel. -- paul moore linux security @ hp - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 1/4] kevent: core files.
On Sat, 2006-07-29 at 19:48 +0400, Evgeniy Polyakov wrote: > On Fri, Jul 28, 2006 at 09:32:42PM -0700, Nicholas Miell ([EMAIL PROTECTED]) > wrote: > > Speaking of API design choices, I saw your OLS paper and was wondering > > if you were familiar with the Solaris port APIs* and, if so, you could > > please comment on how your proposed event channels are different/better. > > As far as it concerns kevents - userspace "ports" are just usual users > of kevents, like timer notifications. Add another syscall to "complete" > requested kevents and you get exactly Solaris ports. > It is fairly simple to implement on top of kevents, I just do not see > immediate benefits from that. > Sorry, I wasn't talking about kevent, I was talking about the interfaces described in "The Need for Asynchronous, Zero-Copy Network I/O" by Ulrich Drepper -- specifically the ec_t type and related functions and the modifications to struct sigevent. -- Nicholas Miell <[EMAIL PROTECTED]> - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[-mm patch] security/selinux/hooks.c: make 4 functions static
On Thu, Jul 27, 2006 at 01:56:39AM -0700, Andrew Morton wrote: >... > Changes since 2.6.18-rc2-mm1: >... > git-net.patch >... > git trees >... This patch makes four needlessly global functions static. Signed-off-by: Adrian Bunk <[EMAIL PROTECTED]> --- security/selinux/hooks.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) --- linux-2.6.18-rc2-mm1-full/security/selinux/hooks.c.old 2006-07-27 20:31:37.0 +0200 +++ linux-2.6.18-rc2-mm1-full/security/selinux/hooks.c 2006-07-27 20:32:46.0 +0200 @@ -3576,7 +3576,7 @@ } } -void selinux_sock_graft(struct sock* sk, struct socket *parent) +static void selinux_sock_graft(struct sock* sk, struct socket *parent) { struct inode_security_struct *isec = SOCK_INODE(parent)->i_security; struct sk_security_struct *sksec = sk->sk_security; @@ -3584,8 +3584,8 @@ isec->sid = sksec->sid; } -int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, - struct request_sock *req) +static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, +struct request_sock *req) { struct sk_security_struct *sksec = sk->sk_security; int err; @@ -3603,7 +3603,8 @@ return 0; } -void selinux_inet_csk_clone(struct sock *newsk, const struct request_sock *req) +static void selinux_inet_csk_clone(struct sock *newsk, + const struct request_sock *req) { struct sk_security_struct *newsksec = newsk->sk_security; @@ -3614,7 +3615,8 @@ time it will have been created and available. */ } -void selinux_req_classify_flow(const struct request_sock *req, struct flowi *fl) +static void selinux_req_classify_flow(const struct request_sock *req, + struct flowi *fl) { fl->secid = req->secid; } - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 1/4] kevent: core files.
On Saturday 29 July 2006 18:18, Ulrich Drepper wrote: > Evgeniy Polyakov wrote: > > Btw, why do we want mapped ring of ready events? > > If user requestd some event, he definitely wants to get them back when > > they are ready, and not to check and then get them? > > Could you please explain more on this issue? > > If of course makes no sense to enter the kernel to actually get the > event. This should be done by storing the event in the ring buffer. > I.e., there are two ways to get an event: > > - with a syscall. This can report as many events at once as the caller > provides space for. And no event which is reported in the run buffer > should be reported this way > > - if there is space, report it in the ring buffer. Yes, the buffer > can be optional, then all events are reported by the system call. > > > So the use case would be like this: > > > wait_and_get_event: > > is buffer empty ? > > yes -> make syscall > > no -> get event from buffer > > > To avoid races, the syscall needs to take a parameter indicating the > last event checked out from the buffer. If in the meantime the kernel > put another event in the buffer the syscall immediately returns. > Similar to what we do in the futex syscall. Couldn't this be done in a general way: Given a fd that supports streaming input, map some user-mem as a ring buffer for input. Maybe the kernel should control the buffer in order to make resizing possible (i.e., TCP zero-copy and window scaling). Hans Henrik - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 2/7] NetLabel: core network changes
> > This is only true wart I see in the patch set from my > > perspective. > > > > You have security_post_accept_hook(), which gets the parent and > > the child socket which is all the information you need, and it > > seems to be invoked at the correct location. > > > > So can you please hook into this location using the security > > level hook we already have? Just check sock->sk->sk_family is > > PF_INET at the top of that hook if you only want to handle > > ipv4 sockets, or something like that. > > > > Could this work? > > > > When preparing and argument stating why this won't work, please > > suggest a nicer name for this af_inet.c hook or some way to make > > it more generic and palatable to us. > > The only reason for having this new hook in inet_accept() is to catch > all the in-kernel "daemons" who do not go through the LSM hooked > accept() code path. I debated putting this hook into the patchset and > in the end figured it was at least worth a shot. If I understand the patch correctly, the openreq inherits cipso from the incoming syn and the syn-ack is then sent with this option. I further see that the child sock inherits options from the openreq already. Could you then please elaborate on the need for explicitly copying options from parent to child? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 1/4] kevent: core files.
Evgeniy Polyakov wrote: > Btw, why do we want mapped ring of ready events? > If user requestd some event, he definitely wants to get them back when > they are ready, and not to check and then get them? > Could you please explain more on this issue? If of course makes no sense to enter the kernel to actually get the event. This should be done by storing the event in the ring buffer. I.e., there are two ways to get an event: - with a syscall. This can report as many events at once as the caller provides space for. And no event which is reported in the run buffer should be reported this way - if there is space, report it in the ring buffer. Yes, the buffer can be optional, then all events are reported by the system call. So the use case would be like this: wait_and_get_event: is buffer empty ? yes -> make syscall no -> get event from buffer To avoid races, the syscall needs to take a parameter indicating the last event checked out from the buffer. If in the meantime the kernel put another event in the buffer the syscall immediately returns. Similar to what we do in the futex syscall. The question is how to best represent the ring buffer. Zach and some others had some ready responses in Ottawa. The important thing is to avoid cache line ping pong when possible. Is the ring buffer absolutely necessary? Probably not. But it has the potential to help quite a bit. Don't look at the problem to solve in the context of heavy I/O operations when another syscall here and there doesn't matter. With this single event mechanism for every possible event the kernel can generate programming can look quite different. E.g., every read() call can implicitly we changed into an async read call followed by a user-level reschedule. This rescheduling allows another thread of execution to run while the read request is processed. I.e., it's basically a setjmp() followed by a goto into the inner loop to get the next event. And now suddenly the event notification mechanism really should be as fast as possible. If we submit basically every request asynchronously and are not creating dedicated threads for specific tasks anymore we a) have a lot more event notifications b) the probability of an event being reported when we want the receive the next one if higher (i.e., the case where no syscall vs syscall makes a difference) Yes, all this will require changes in the way programs a written but we shouldn't limit the way we can write programs unnecessarily. I think that given increasing discrepancies in relative speed/latency of the peripherals and the CPU this is one possible solution to keep the CPUs busy without resorting to a gazillion separate threads in each program. -- ➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖ signature.asc Description: OpenPGP digital signature
Re: [RFC 1/4] kevent: core files.
On Fri, Jul 28, 2006 at 09:32:42PM -0700, Nicholas Miell ([EMAIL PROTECTED]) wrote: > Speaking of API design choices, I saw your OLS paper and was wondering > if you were familiar with the Solaris port APIs* and, if so, you could > please comment on how your proposed event channels are different/better. As far as it concerns kevents - userspace "ports" are just usual users of kevents, like timer notifications. Add another syscall to "complete" requested kevents and you get exactly Solaris ports. It is fairly simple to implement on top of kevents, I just do not see immediate benefits from that. > -- > Nicholas Miell <[EMAIL PROTECTED]> -- Evgeniy Polyakov - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 1/4] kevent: core files.
On Fri, Jul 28, 2006 at 08:38:02PM -0700, Ulrich Drepper ([EMAIL PROTECTED]) wrote: > Zach Brown wrote: > > Ulrich, would you be satisfied if we didn't > > have the userspace mapped ring on the first pass and only had a > > collection syscall? > > I'm not the one to make a call but why rush things? Let's do it right > from the start. Later changes can only lead to problems with users of > the earlier interface. Btw, why do we want mapped ring of ready events? If user requestd some event, he definitely wants to get them back when they are ready, and not to check and then get them? Could you please explain more on this issue? > -- > ??? Ulrich Drepper ??? Red Hat, Inc. ??? 444 Castro St ??? Mountain View, CA > ??? > -- Evgeniy Polyakov - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] Mobile IPv6 introduction
Hi, First of all and to be fair let me introduce my bias -- i'm also developing a mobility framework, which although not MIPv6-specific, does support it (we'll be running a large set of tests during the following month, hopefully culminating in an initial public release in september). In general, i'm all for integrating mobility required code into the kernel, however i have some comments regarding your approaches. Due to the large amount of small patches which are difficult to comment (please send an e-mail with a list of them next time please) i'll just leave a couple of high level comments: - In general, lot's of places in the IPv6 stack don't take the source address into consideration and generically only use destination as key, i think this is a major setback that should be approached individually. - I don't like having the individual MIPv6-specific messages checking in the kernel because feature-wise this is not scalable. Only data-path specific processing should be done in the kernel IMO (RT2 hdr processing, HOA DSTopt processing with address swapping, etc) Introducing new mobility header message type would involve modify- ing the kernel when there would be no other reason to do so (you would then need NEMO-specific code in the kernel, FMIPv6-specific code, etc). Taking the error reporting as an example, what i would prefer would be a way of either signaling the kernel ICMPv6 component to send ParamProb or other types of errors (difficult to support), or instead introducing a new datagram control message that would enable the control application to retrieve the original network headers (although possibly modified) and send the ICMPv6 message itself (which was my choice). - Maybe others disagree, but i don't like having a "Route optimization" mode in XFRM. From my POV, "Route optimization" is one kind of transformation specific to MIPv6. Other protocols require other kind of transformations. I think XFRM should be instead extended to support generic transformations, where the Mobile IPv6-specific one would implement a RO transform in order to support it's binding cache. Also, these new modes are not "advanced" but instead "Mobile IPv6 specific". Best regards, Hugo On Sat, Jul 29, 2006 at 06:23:32PM +0900, Masahide NAKAMURA wrote: > Hello, > > Let me introduce Mobile IPv6(RFC3775) patch and its outline. > > We USAGI project and HUT Go/Core project have developed > for Mobile IPv6(MIPv6) stack on 2.6 tree as MIPL2 for several years. > Our aim is to make kernel patch smaller (than MIPL1 which is for > 2.4 kernel). > > We find out we have 4 categories for the patch: > > 1. IPv6 policy routing > 2. IPsec MIGRATE > 3. Advanced XFRM for Correspondent Node(CN) > 4. MISC > > 3, 4 are MIPv6 specific feature but 1, 2 are not. > It can be discussed in parallel about 1, 2, 3 because they > don't depend on others. > > > 1. IPv6 policy routing > Thomas and Yoshifuji have already started to discuss and work for it. > This is required by Mobile Node(MN) and used by Home Agent(HA). > > 2. IPsec MIGRATE > This is an interface to update IPsec end-point address of SAD/SPD. > (there is an IETF draft: draft-sugimoto-mip6-pfkey-migrate-XX) > This is required by MN and HA to use IPsec tunnel. > > 3. Advanced XFRM for CN > "Route optimization" defined MIPv6 specification > is designed as XFRM extension. IPv6 extension headers > handling is included, too. > This feature is required by all MIPv6 nodes(CN, MN, HA) then it can > be said MIPv6 platform. > > 4. MISC > This is a set of small patches but works with the above categories > since they are finally confirmed as the MIPv6 node behavior; > e.g. home addressing for MN, proxy forwarding for HA. > > > At first I'll send patches about category "3" very soon, just for review. > Can you check them? > > Thanks, > > -- > Masahide NAKAMURA > > > > > > > - > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to [EMAIL PROTECTED] > More majordomo info at http://vger.kernel.org/majordomo-info.html signature.asc Description: Digital signature
Re: Regarding offloading IPv6 addrconf and ndisc
Hi Jamal, Through this discussion i've identified three points: one is that some believe control and data should be kept synchronized; the other is how some (including all of the first :-) think control should remain inside the kernel; and finally you and me so far who believe they should be separated for increased flexibility. If we consider the first point, i would too have difficulties accepting the second one, taking the same considerations Stephen mentioned, where an application could possibly bork the kernel. So, first of all, we need to settle whether data really needs to be in-sync with control (already assuming the complexity control is gaining). Personally i think the answer is clear; the overall throughput depends on the amount of time spent in a single state. Thus, the data path should be well contained and depend only on the current state; while control executes in parallel as it's state transitions are much longer and might depend on multiple sub-transitions (communicating with peers, etc). Deciding whether control should remain inside the kernel or not is another story; as you point out, people generically don't like to depend on daemons. I understand this point, and i think a solution that would keep both parties happy would be to have the current functionality inside the kernel while at the same time allowing control daemons to take over and support additional complex features. I would say that the generic worries such as 'how do we handle out of memory', or 'what if it crashes' or even 'what if it is overloaded' apply both to the kernel and to a possible user-space application. - As this control daemon is important for the proper interaction of the host with the network, we would reduce it's chances of being OOM killed (while at the same time implementing algorithms to prevent DoS by state flooding); - Regarding the crashes, i think it is better for a system to have an application rather than a kernel component crash as it might be seamlessly restarted to recover. I would also say that the complex- ity of the code is the same (or worst if in the kernel) to support exactly the same features; - The overloading problem also applies to the kernel, and would be something that must be considered by either implementation; Don't forget that having this functionality in a daemon would also allow for easier updates (including updates without having to reboot your machine) besides offering a greater degree of flexibility. Let me also point out to any IKE daemon, where the SA/SP database is kept in kernel, but is provided for by the daemon using explicit requests by the kernel (ACQUIREs). If we consider neighbor discovery for instance, if configured to do so, and as an example, instead of sending an IPv6 NS, the kernel could netlink broadcast (or unicast to a specific controller) the request due to an entry being STALEd and being required where the daemon would then update the entry to REACHABLE. I'm sure some of you will continue to disagree, but i would really like to move this decision to the user (or system deployer). Hugo signature.asc Description: Digital signature
[NET]: Fix ___pskb_trim when entire frag_list needs dropping
On Thu, Jul 13, 2006 at 07:03:41PM +1000, herbert wrote: > > This needs to go into stable as well. In fact, there is another unrelated > bug with exactly the same symptoms which was inadvertently fixed by the > GSO patches. So I'll send a simpler fix for that to stable. > > [NET]: Update frag_list in pskb_trim Marco told me that he was still seeing the same problem. Turns out that my patch missed one important case. I hope this is really the last time I have to look at this bug :) [NET]: Fix ___pskb_trim when entire frag_list needs dropping When the trim point is within the head and there is no paged data, ___pskb_trim fails to drop the first element in the frag_list. This patch fixes this by moving the len <= offset case out of the page data loop. This patch also adds a missing kfree_skb on the frag that we just cloned. Signed-off-by: Herbert Xu <[EMAIL PROTECTED]> Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt -- diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 476aa39..d236f02 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -846,7 +846,11 @@ int ___pskb_trim(struct sk_buff *skb, un unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC return err; - for (i = 0; i < nfrags; i++) { + i = 0; + if (offset >= len) + goto drop_pages; + + for (; i < nfrags; i++) { int end = offset + skb_shinfo(skb)->frags[i].size; if (end < len) { @@ -854,9 +858,9 @@ int ___pskb_trim(struct sk_buff *skb, un continue; } - if (len > offset) - skb_shinfo(skb)->frags[i++].size = len - offset; + skb_shinfo(skb)->frags[i++].size = len - offset; +drop_pages: skb_shinfo(skb)->nr_frags = i; for (; i < nfrags; i++) @@ -864,7 +868,7 @@ int ___pskb_trim(struct sk_buff *skb, un if (skb_shinfo(skb)->frag_list) skb_drop_fraglist(skb); - break; + goto done; } for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp); @@ -879,6 +883,7 @@ int ___pskb_trim(struct sk_buff *skb, un return -ENOMEM; nfrag->next = frag->next; + kfree_skb(frag); frag = nfrag; *fragp = frag; } @@ -897,6 +902,7 @@ int ___pskb_trim(struct sk_buff *skb, un break; } +done: if (len > skb_headlen(skb)) { skb->data_len -= skb->len - len; skb->len = len; - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5] [IPV6]: Multiple Routing Tables
* YOSHIFUJI Hideaki / ?$B5HF#1QL@ <[EMAIL PROTECTED]> 2006-07-29 13:13 > Well, one design consideration that I have had for several months > is performance impact. > > Previously, we directly use address, ifindex etc., not flowi, > in IPv6 routing code except for ip6_route_output(). > This patch changes them to use flowi. > I know this should work and it is a good way for abstraction. > However, initializing flowi for IPv6 is more expensive than > one for IPv4, and it would result in poor performance (especially > without CONFIG_IPV6_MULTIPLE_TABLES). Do you have numbers for this? Personally I'm more worried about the number of locks needed for a lookup and the selection. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/20] [PATCH] [XFRM] IPV6: Support Mobile IPv6 extension headers sorting.
Support Mobile IPv6 extension headers sorting for two transformation policies. Mobile IPv6 extension headers should be placed after IPsec transport mode, but before transport AH when outbound. --- net/ipv6/xfrm6_state.c | 28 ++-- 1 files changed, 26 insertions(+), 2 deletions(-) diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 1a5cc65..8d431ab 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c @@ -178,7 +178,19 @@ __xfrm6_state_sort(struct xfrm_state **d if (j == n) goto end; - /* XXX: Rule 2: select MIPv6 RO or inbound trigger */ + /* Rule 2: select MIPv6 RO or inbound trigger */ +#ifdef CONFIG_IPV6_MIP6 + for (i = 0; i < n; i++) { + if (src[i] && + (src[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION || +src[i]->props.mode == XFRM_MODE_IN_TRIGGER)) { + dst[j++] = src[i]; + src[i] = NULL; + } + } + if (j == n) + goto end; +#endif /* Rule 3: select IPsec transport AH */ for (i = 0; i < n; i++) { @@ -231,7 +243,19 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst if (j == n) goto end; - /* XXX: Rule 2: select MIPv6 RO or inbound trigger */ + /* Rule 2: select MIPv6 RO or inbound trigger */ +#ifdef CONFIG_IPV6_MIP6 + for (i = 0; i < n; i++) { + if (src[i] && + (src[i]->mode == XFRM_MODE_ROUTEOPTIMIZATION || +src[i]->mode == XFRM_MODE_IN_TRIGGER)) { + dst[j++] = src[i]; + src[i] = NULL; + } + } + if (j == n) + goto end; +#endif /* Rule 3: select IPsec tunnel */ for (i = 0; i < n; i++) { -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 12/20] [PATCH] [IPV6] MIP6: Add routing header type 2 transformation.
Add routing header type 2 transformation for Mobile IPv6. Based on MIPL2 kernel patch. --- include/net/mip6.h | 31 + net/ipv6/Makefile |3 + net/ipv6/af_inet6.c |9 ++ net/ipv6/mip6.c | 186 +++ 4 files changed, 229 insertions(+), 0 deletions(-) diff --git a/include/net/mip6.h b/include/net/mip6.h new file mode 100644 index 000..644b8b6 --- /dev/null +++ b/include/net/mip6.h @@ -0,0 +1,31 @@ +/* + * Copyright (C)2003-2006 Helsinki University of Technology + * Copyright (C)2003-2006 USAGI/WIDE Project + * + * 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 + */ +/* + * Authors: + * Noriaki TAKAMIYA @USAGI + * Masahide NAKAMURA @USAGI + * YOSHIFUJI Hideaki @USAGI + */ +#ifndef _NET_MIP6_H +#define _NET_MIP6_H + +extern int mip6_init(void); +extern void mip6_fini(void); + +#endif diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile index a760b09..3d46adb 100644 --- a/net/ipv6/Makefile +++ b/net/ipv6/Makefile @@ -13,6 +13,9 @@ ipv6-objs := af_inet6.o anycast.o ip6_ou ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \ xfrm6_output.o ipv6-$(CONFIG_NETFILTER) += netfilter.o + +ipv6-$(CONFIG_IPV6_MIP6) += mip6.o + ipv6-objs += $(ipv6-y) obj-$(CONFIG_INET6_AH) += ah6.o diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e19457f..e40af02 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -60,6 +60,9 @@ #include #ifdef CONFIG_IPV6_TUNNEL #include #endif +#ifdef CONFIG_IPV6_MIP6 +#include +#endif #include #include @@ -859,6 +862,9 @@ #endif ipv6_frag_init(); ipv6_nodata_init(); ipv6_destopt_init(); +#ifdef CONFIG_IPV6_MIP6 + mip6_init(); +#endif /* Init v6 transport protocols. */ udpv6_init(); @@ -922,6 +928,9 @@ #ifdef CONFIG_PROC_FS tcp6_proc_exit(); raw6_proc_exit(); #endif +#ifdef CONFIG_IPV6_MIP6 + mip6_fini(); +#endif /* Cleanup code parts. */ sit_cleanup(); ip6_flowlabel_cleanup(); diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c new file mode 100644 index 000..0fa495a --- /dev/null +++ b/net/ipv6/mip6.c @@ -0,0 +1,186 @@ +/* + * Copyright (C)2003-2006 Helsinki University of Technology + * Copyright (C)2003-2006 USAGI/WIDE Project + * + * 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 + */ +/* + * Authors: + * Noriaki TAKAMIYA @USAGI + * Masahide NAKAMURA @USAGI + */ + +#include +#include +#include +#include +#include +#include +#include + +static xfrm_address_t *mip6_xfrm_addr(struct xfrm_state *x, + xfrm_address_t *addr) +{ + return x->coaddr; +} + +/* + * Routing Header type 2 + */ + +static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb) +{ + struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data; + + if (!ipv6_addr_equal(&rt2->addr, (struct in6_addr *)x->coaddr) && + !ipv6_addr_any((struct in6_addr *)x->coaddr)) + return -ENOENT; + + return rt2->rt_hdr.nexthdr; +} + +/* Routing Header type 2 is inserted. + * IP Header's dst address is replaced with Routing Header's Home Address. + */ +static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb) +{ + struct ipv6hdr *iph; + struct rt2_hdr *rt2; + u8 nexthdr; + + iph = (struct ipv6hdr *)skb->data; + iph->payload_len = htons(skb->len - sizeof(*iph)); + + nexthdr = *skb->nh.raw; + *skb->nh.raw = IPPROTO_ROUTING; + + rt2 = (struct rt2_hdr *)skb->h.raw; + rt2->rt_hdr
[PATCH 8/20] [PATCH] [IPV6] MIP6: Add home address option definition.
Add home address option definition for Mobile IPv6. Based on MIPL2 kernel patch. --- include/linux/in6.h |1 + include/linux/ipv6.h | 10 ++ 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/include/linux/in6.h b/include/linux/in6.h index 304aaed..086ec2a 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -142,6 +142,7 @@ #define IPV6_TLV_PAD0 0 #define IPV6_TLV_PADN 1 #define IPV6_TLV_ROUTERALERT 5 #define IPV6_TLV_JUMBO 194 +#define IPV6_TLV_HAO 201 /* home address option */ /* * IPV6 socket options diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 9152d4b..43e2e70 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -87,6 +87,16 @@ struct rt2_hdr { #define rt2_type rt_hdr.type }; +/* + * home address option in destination options header + */ + +struct destopt_hao { + __u8type; + __u8length; + struct in6_addr addr; +} __attribute__ ((__packed__)); + struct ipv6_auth_hdr { __u8 nexthdr; __u8 hdrlen; /* This one is measured in 32 bit units! */ -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 17/20] [PATCH] [IPV6] MIP6: Add receiving mobility header functions through raw socket.
Like ICMPv6, mobility header is handled through raw socket. In inbound case, check only whether ICMPv6 error should be sent as a reply or not by kernel. Based on MIPL2 kernel patch. --- include/net/mip6.h |4 ++ net/ipv6/mip6.c| 87 net/ipv6/raw.c | 29 + 3 files changed, 119 insertions(+), 1 deletions(-) diff --git a/include/net/mip6.h b/include/net/mip6.h index fd43178..68263c6 100644 --- a/include/net/mip6.h +++ b/include/net/mip6.h @@ -25,6 +25,9 @@ #ifndef _NET_MIP6_H #define _NET_MIP6_H +#include +#include + #define MIP6_OPT_PAD_1 0 #define MIP6_OPT_PAD_N 1 @@ -53,5 +56,6 @@ #define IP6_MH_TYPE_MAX IP6_MH_TYPE_BER extern int mip6_init(void); extern void mip6_fini(void); +extern int mip6_mh_filter(struct sock *sk, struct sk_buff *skb); #endif diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index ebe2f76..fb973d9 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c @@ -27,7 +27,10 @@ #include #include #include #include +#include +#include #include +#include #include #include @@ -58,6 +61,90 @@ static inline void *mip6_padn(__u8 *data } /* + * Mobility Header + */ + +static int _mh_len(int type) +{ + int len = 0; + + switch (type) { + case IP6_MH_TYPE_BRR: + len = 0; + break; + case IP6_MH_TYPE_HOTI: + case IP6_MH_TYPE_COTI: + case IP6_MH_TYPE_BU: + case IP6_MH_TYPE_BACK: + len = 1; + break; + case IP6_MH_TYPE_HOT: + case IP6_MH_TYPE_COT: + case IP6_MH_TYPE_BERROR: + len = 2; + break; + } + return len; +} + +static inline void mip6_param_prob(struct sk_buff *skb, int code, int pos) +{ + icmpv6_send(skb, ICMPV6_PARAMPROB, code, pos, skb->dev); +} + +int mip6_mh_filter(struct sock *sk, struct sk_buff *skb) +{ + struct ip6_mh *mh; + int mhlen; + + if (!pskb_may_pull(skb, (skb->h.raw - skb->data) + 8) || + !pskb_may_pull(skb, (skb->h.raw - skb->data) + ((skb->h.raw[1] + 1) << 3))) + return -1; + + mh = (struct ip6_mh *)skb->h.raw; + + if (mh->ip6mh_hdrlen < _mh_len(mh->ip6mh_type)) { + LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n", + mh->ip6mh_hdrlen, _mh_len(mh->ip6mh_type)); + mip6_param_prob(skb, 0, (&mh->ip6mh_hdrlen) - skb->nh.raw); + return -1; + } + mhlen = (mh->ip6mh_hdrlen + 1) << 3; + + if (skb->ip_summed == CHECKSUM_HW) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, + &skb->nh.ipv6h->daddr, + mhlen, IPPROTO_MH, + skb->csum)) { + LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH hw checksum failed\n"); + skb->ip_summed = CHECKSUM_NONE; + } + } + if (skb->ip_summed == CHECKSUM_NONE) { + if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, + &skb->nh.ipv6h->daddr, + mhlen, IPPROTO_MH, + skb_checksum(skb, 0, mhlen, 0))) { + LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n", + NIP6(skb->nh.ipv6h->saddr), + NIP6(skb->nh.ipv6h->daddr)); + return -1; + } + skb->ip_summed = CHECKSUM_UNNECESSARY; + } + + if (mh->ip6mh_proto != IPPROTO_NONE) { + LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n", + mh->ip6mh_proto); + mip6_param_prob(skb, 0, (&mh->ip6mh_proto) - skb->nh.raw); + return -1; + } + + return 0; +} + +/* * Destination Options Header */ diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index fa1ce0a..e0faf4d 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -50,6 +50,9 @@ #include #include #include #include +#ifdef CONFIG_IPV6_MIP6 +#include +#endif #include #include @@ -169,8 +172,32 @@ int ipv6_raw_deliver(struct sk_buff *skb sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif); while (sk) { + int filtered; + delivered = 1; - if (nexthdr != IPPROTO_ICMPV6 || !icmpv6_filter(sk, skb)) { + switch (nexthdr) { + case IPPROTO_ICMPV6: + filtered = icmpv6_filter(sk, skb); + break; +#ifdef CONFIG_IPV6_MIP6 +
[PATCH 19/20] [PATCH] [IPV6] MIP6: Add sending mobility header functions through raw socket.
Mobility header is built by user-space and sent through raw socket. Kernel just extracts its type to flow. Based on MIPL2 kernel patch. --- net/ipv6/raw.c | 17 + 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index e0faf4d..0e8dca2 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -608,6 +608,9 @@ static void rawv6_probe_proto_opt(struct struct iovec *iov; u8 __user *type = NULL; u8 __user *code = NULL; +#ifdef CONFIG_IPV6_MIP6 + u8 len = 0; +#endif int probed = 0; int i; @@ -639,6 +642,20 @@ static void rawv6_probe_proto_opt(struct probed = 1; } break; +#ifdef CONFIG_IPV6_MIP6 + case IPPROTO_MH: + if (iov->iov_base && iov->iov_len < 1) + break; + /* check if type field is readable or not. */ + if (iov->iov_len > 2 - len) { + u8 __user *p = iov->iov_base; + get_user(fl->fl_mh_type, &p[2 - len]); + probed = 1; + } else + len += iov->iov_len; + + break; +#endif default: probed = 1; break; -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 18/20] [PATCH] [IPV6] MIP6: Ignore mobility headers if it is rejected.
Ignore mobility headers if it is rejected by route optimization. Mobility headers should be bypassed for any route optimization and application should use transformation policy and wild-card states corerctly to catch mobility headers prior than other packets. This case which such reject is occurred may be either missing poilcy or erroneous policy is inserted to kernel. Based on MIPL2 kernel patch. --- net/ipv6/mip6.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index fb973d9..43d0b53 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c @@ -243,6 +243,9 @@ static int mip6_destopt_reject(struct xf struct timeval stamp; int err = 0; + if (unlikely(fl->proto == IPPROTO_MH && fl->fl_mh_type <= IP6_MH_TYPE_MAX)) + goto out; + if (likely(opt->dsthao)) { offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO); if (likely(offset >= 0)) -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 15/20] [PATCH] [XFRM] STATE: Add Mobile IPv6 route optimization protocols to netlink interface.
Add Mobile IPv6 route optimization protocols to netlink interface. Route optimization states carry care-of address. Based on MIPL2 kernel patch. --- net/xfrm/xfrm_user.c | 22 ++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index cf62208..e45d25f 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -27,6 +27,9 @@ #include #include #include #include +#ifdef CONFIG_IPV6_MIP6 +#include +#endif static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type) { @@ -171,7 +174,26 @@ #endif goto out; break; +#ifdef CONFIG_IPV6_MIP6 + case IPPROTO_DSTOPTS: + case IPPROTO_ROUTING: +#ifdef CONFIG_XFRM_ADVANCED + if (xfrma[XFRMA_ALG_COMP-1] || + xfrma[XFRMA_ALG_AUTH-1] || + xfrma[XFRMA_ALG_CRYPT-1]|| + xfrma[XFRMA_ENCAP-1]|| + xfrma[XFRMA_SEC_CTX - 1]|| + !xfrma[XFRMA_ADDR-1]) + goto out; + break; +#else + err = -ENOSYS; + goto out; +#endif +#endif + default: + err = -EPROTONOSUPPORT; goto out; }; -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/20] [PATCH] [IPV6] MIP6: Add inbound interface of routing header type 2.
Add inbound interface of routing header type 2 for Mobile IPv6. Based on MIPL2 kernel patch. --- include/net/addrconf.h |7 + net/ipv6/exthdrs.c | 71 +++- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 750e250..71fc890 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -62,6 +62,13 @@ extern int addrconf_set_dstaddr(void _ extern int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict); +/* XXX: this is a placeholder till addrconf supports */ +#ifdef CONFIG_IPV6_MIP6 +static inline int ipv6_chk_home_addr(struct in6_addr *addr) +{ + return 0; +} +#endif extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *dev, int strict); diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index a18d425..138cb12 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -43,6 +43,9 @@ #include #include #include #include +#ifdef CONFIG_IPV6_MIP6 +#include +#endif #include @@ -219,7 +222,7 @@ static int ipv6_rthdr_rcv(struct sk_buff { struct sk_buff *skb = *skbp; struct inet6_skb_parm *opt = IP6CB(skb); - struct in6_addr *addr; + struct in6_addr *addr = NULL; struct in6_addr daddr; int n, i; @@ -244,6 +247,23 @@ static int ipv6_rthdr_rcv(struct sk_buff looped_back: if (hdr->segments_left == 0) { + switch (hdr->type) { +#ifdef CONFIG_IPV6_MIP6 + case IPV6_SRCRT_TYPE_2: + /* Silently discard type 2 header unless it was +* processed by own +*/ + if (!addr) { + IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); + kfree_skb(skb); + return -1; + } + break; +#endif + default: + break; + } + opt->lastopt = skb->h.raw - skb->nh.raw; opt->srcrt = skb->h.raw - skb->nh.raw; skb->h.raw += (hdr->hdrlen + 1) << 3; @@ -253,17 +273,29 @@ looped_back: return 1; } - if (hdr->type != IPV6_SRCRT_TYPE_0) { + switch (hdr->type) { + case IPV6_SRCRT_TYPE_0: + if (hdr->hdrlen & 0x01) { + IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); + icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); + return -1; + } + break; +#ifdef CONFIG_IPV6_MIP6 + case IPV6_SRCRT_TYPE_2: + /* Silently discard invalid RTH type 2 */ + if (hdr->hdrlen != 2 || hdr->segments_left != 1) { + IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); + kfree_skb(skb); + return -1; + } + break; +#endif + default: IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); return -1; } - - if (hdr->hdrlen & 0x01) { - IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); - icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); - return -1; - } /* * This is the routing header forwarding algorithm from @@ -303,6 +335,29 @@ looped_back: addr = rthdr->addr; addr += i - 1; + switch (hdr->type) { +#ifdef CONFIG_IPV6_MIP6 + case IPV6_SRCRT_TYPE_2: + if (__xfrm6_rcv_one(skb, + (xfrm_address_t *)addr, + (xfrm_address_t *)&skb->nh.ipv6h->saddr, + IPPROTO_ROUTING) < 0) { + IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); + kfree_skb(skb); + return -1; + } + + if (!ipv6_chk_home_addr(addr)) { + IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); + kfree_skb(skb); + return -1; + } + break; +#endif + default: + break; + } + if (ipv6_addr_is_multicast(addr)) { IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); kfree_skb(skb); -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info
[PATCH 16/20] [PATCH] [IPV6] MIP6: Add Mobility header definition.
Add Mobility header definition for Mobile IPv6. Based on MIPL2 kernel patch. --- include/linux/in6.h |1 + include/net/flow.h |9 + include/net/ipv6.h |1 + include/net/mip6.h | 23 +++ 4 files changed, 34 insertions(+), 0 deletions(-) diff --git a/include/linux/in6.h b/include/linux/in6.h index 086ec2a..d776829 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -134,6 +134,7 @@ #define IPPROTO_FRAGMENT44 /* IPv6 frag #define IPPROTO_ICMPV6 58 /* ICMPv6 */ #define IPPROTO_NONE 59 /* IPv6 no next header */ #define IPPROTO_DSTOPTS60 /* IPv6 destination options */ +#define IPPROTO_MH 135 /* IPv6 mobility header */ /* * IPv6 TLV options. diff --git a/include/net/flow.h b/include/net/flow.h index 04d89f7..650dfaf 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -72,12 +72,21 @@ #define FLOWI_FLAG_MULTIPATHOLDROUTE 0x0 } dnports; __u32 spi; + +#ifdef CONFIG_IPV6_MIP6 + struct { + __u8type; + } mht; +#endif } uli_u; #define fl_ip_sportuli_u.ports.sport #define fl_ip_dportuli_u.ports.dport #define fl_icmp_type uli_u.icmpt.type #define fl_icmp_code uli_u.icmpt.code #define fl_ipsec_spi uli_u.spi +#ifdef CONFIG_IPV6_MIP6 +#define fl_mh_type uli_u.mht.type +#endif } __attribute__((__aligned__(BITS_PER_LONG/8))); #define FLOW_DIR_IN0 diff --git a/include/net/ipv6.h b/include/net/ipv6.h index cbe72ea..7688534 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -40,6 +40,7 @@ #define NEXTHDR_AUTH 51 /* Authenticati #define NEXTHDR_ICMP 58 /* ICMP for IPv6. */ #define NEXTHDR_NONE 59 /* No next header */ #define NEXTHDR_DEST 60 /* Destination options header. */ +#define NEXTHDR_MOBILITY 135 /* Mobility header. */ #define NEXTHDR_MAX255 diff --git a/include/net/mip6.h b/include/net/mip6.h index 42b65ba..fd43178 100644 --- a/include/net/mip6.h +++ b/include/net/mip6.h @@ -28,6 +28,29 @@ #define _NET_MIP6_H #define MIP6_OPT_PAD_1 0 #define MIP6_OPT_PAD_N 1 +/* + * Mobility Header + */ +struct ip6_mh { + __u8ip6mh_proto; + __u8ip6mh_hdrlen; + __u8ip6mh_type; + __u8ip6mh_reserved; + __u16 ip6mh_cksum; + /* Followed by type specific messages */ + __u8data[0]; +} __attribute__ ((__packed__)); + +#define IP6_MH_TYPE_BRR0 /* Binding Refresh Request */ +#define IP6_MH_TYPE_HOTI 1 /* HOTI Message */ +#define IP6_MH_TYPE_COTI 2 /* COTI Message */ +#define IP6_MH_TYPE_HOT3 /* HOT Message */ +#define IP6_MH_TYPE_COT4 /* COT Message */ +#define IP6_MH_TYPE_BU 5 /* Binding Update */ +#define IP6_MH_TYPE_BACK 6 /* Binding ACK */ +#define IP6_MH_TYPE_BERROR 7 /* Binding Error */ +#define IP6_MH_TYPE_MAXIP6_MH_TYPE_BERROR + extern int mip6_init(void); extern void mip6_fini(void); -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 20/20] [PATCH] [IPV6] MIP6: Transformation support mobility header.
Transformation support mobility header. Based on MIPL2 kernel patch. --- include/net/xfrm.h |5 + net/ipv6/xfrm6_policy.c | 15 +++ 2 files changed, 20 insertions(+), 0 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 0d14b1f..85398b0 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -587,6 +587,11 @@ u16 xfrm_flowi_sport(struct flowi *fl) case IPPROTO_ICMPV6: port = htons(fl->fl_icmp_type); break; +#ifdef CONFIG_IPV6_MIP6 + case IPPROTO_MH: + port = htons(fl->fl_mh_type); + break; +#endif default: port = 0; /*XXX*/ } diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index eaa1b0d..98e407e 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -19,6 +19,9 @@ #include #include #include #include +#ifdef CONFIG_IPV6_MIP6 +#include +#endif static struct dst_ops xfrm6_dst_ops; static struct xfrm_policy_afinfo xfrm6_policy_afinfo; @@ -247,6 +250,18 @@ _decode_session6(struct sk_buff *skb, st fl->proto = nexthdr; return; +#ifdef CONFIG_IPV6_MIP6 + case IPPROTO_MH: + if (pskb_may_pull(skb, skb->nh.raw + offset + 3 - skb->data)) { + struct ip6_mh *mh; + mh = (struct ip6_mh *)exthdr; + + fl->fl_mh_type = mh->ip6mh_type; + } + fl->proto = nexthdr; + return; +#endif + /* XXX Why are there these headers? */ case IPPROTO_AH: case IPPROTO_ESP: -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/20] [PATCH] [IPV6]: Find option offset by type.
This is a helper to search option offset from extension header which can carry TLV option like destination options header. Mobile IPv6 home address option will use it. Based on MIPL2 kernel patch. --- include/net/ipv6.h |2 ++ net/ipv6/exthdrs.c | 43 +++ 2 files changed, 45 insertions(+), 0 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 4abedb8..2e78433 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -504,6 +504,8 @@ extern int ipv6_skip_exthdr(const stru extern int ipv6_ext_hdr(u8 nexthdr); +extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type); + extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr); diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 138cb12..fbedad9 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -49,6 +49,49 @@ #endif #include +int ipv6_find_tlv(struct sk_buff *skb, int offset, int type) +{ + int packet_len = skb->tail - skb->nh.raw; + struct ipv6_opt_hdr *hdr; + int len; + + if (offset + 2 > packet_len) + goto bad; + hdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); + len = ((hdr->hdrlen + 1) << 3); + + if (offset + len > packet_len) + goto bad; + + offset += 2; + len -= 2; + + while (len > 0) { + int opttype = skb->nh.raw[offset]; + int optlen; + + if (opttype == type) + return offset; + + switch (opttype) { + case IPV6_TLV_PAD0: + optlen = 1; + break; + default: + optlen = skb->nh.raw[offset + 1] + 2; + if (optlen > len) + goto bad; + break; + } + offset += optlen; + len -= optlen; + } + /* not_found */ + return -1; + bad: + return -1; +} + /* * Parsing tlv encoded headers. * -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 13/20] [PATCH] [IPV6] MIP6: Add destination options header transformation.
Add destination options header transformation for Mobile IPv6. Based on MIPL2 kernel patch. --- include/net/mip6.h |3 + net/ipv6/mip6.c| 167 2 files changed, 170 insertions(+), 0 deletions(-) diff --git a/include/net/mip6.h b/include/net/mip6.h index 644b8b6..42b65ba 100644 --- a/include/net/mip6.h +++ b/include/net/mip6.h @@ -25,6 +25,9 @@ #ifndef _NET_MIP6_H #define _NET_MIP6_H +#define MIP6_OPT_PAD_1 0 +#define MIP6_OPT_PAD_N 1 + extern int mip6_init(void); extern void mip6_fini(void); diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index 0fa495a..5721cf8 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c @@ -36,6 +36,165 @@ static xfrm_address_t *mip6_xfrm_addr(st return x->coaddr; } +static inline unsigned int calc_padlen(unsigned int len, unsigned int n) +{ + return (n - len + 16) & 0x7; +} + +static inline void *mip6_padn(__u8 *data, __u8 padlen) +{ + if (!data) + return NULL; + if (padlen == 1) { + data[0] = MIP6_OPT_PAD_1; + } else if (padlen > 1) { + data[0] = MIP6_OPT_PAD_N; + data[1] = padlen - 2; + if (padlen > 2) + memset(data+2, 0, data[1]); + } + return data + padlen; +} + +/* + * Destination Options Header + */ + +static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb) +{ + struct ipv6hdr *iph = skb->nh.ipv6h; + struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data; + + if (!ipv6_addr_equal(&iph->saddr, (struct in6_addr *)x->coaddr) && + !ipv6_addr_any((struct in6_addr *)x->coaddr)) + return -ENOENT; + + return destopt->nexthdr; +} + +/* Destination Option Header is inserted. + * IP Header's src address is replaced with Home Address Option in + * Destination Option Header. + */ +static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb) +{ + struct ipv6hdr *iph; + struct ipv6_destopt_hdr *dstopt; + struct destopt_hao *hao; + u8 nexthdr; + int len; + + iph = (struct ipv6hdr *)skb->data; + iph->payload_len = htons(skb->len - sizeof(*iph)); + + nexthdr = *skb->nh.raw; + *skb->nh.raw = IPPROTO_DSTOPTS; + + dstopt = (struct ipv6_destopt_hdr *)skb->h.raw; + dstopt->nexthdr = nexthdr; + + hao = mip6_padn((char *)(dstopt + 1), + calc_padlen(sizeof(*dstopt), 6)); + + hao->type = IPV6_TLV_HAO; + hao->length = sizeof(*hao) - 2; + BUG_TRAP(hao->length == 16); + + len = ((char *)hao - (char *)dstopt) + sizeof(*hao); + + memcpy(&hao->addr, &iph->saddr, sizeof(hao->addr)); + memcpy(&iph->saddr, x->coaddr, sizeof(iph->saddr)); + + BUG_TRAP(len == x->props.header_len); + dstopt->hdrlen = (x->props.header_len >> 3) - 1; + + return 0; +} + +static int mip6_destopt_place_find(struct xfrm_state *x, struct sk_buff *skb, + u8 **nexthdr) +{ + u16 offset = sizeof(struct ipv6hdr); + struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.ipv6h + 1); + unsigned int packet_len = skb->tail - skb->nh.raw; + int found_rhdr = 0; + + *nexthdr = &skb->nh.ipv6h->nexthdr; + + while (offset + 1 <= packet_len) { + + switch (**nexthdr) { + case NEXTHDR_HOP: + break; + case NEXTHDR_ROUTING: + found_rhdr = 1; + break; + case NEXTHDR_DEST: + /* +* HAO MUST NOT appear more than once. +* XXX: It is better to try to find by the end of +* XXX: packet if HAO exists. +*/ + if (ipv6_find_tlv(skb, offset, IPV6_TLV_HAO) >= 0) { + LIMIT_NETDEBUG(KERN_WARNING "mip6: hao exists already, override\n"); + return offset; + } + + if (found_rhdr) + return offset; + + break; + default: + return offset; + } + + offset += ipv6_optlen(exthdr); + *nexthdr = &exthdr->nexthdr; + exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); + } + + return offset; +} + +static int mip6_destopt_init_state(struct xfrm_state *x) +{ + if (x->id.spi) { + printk(KERN_INFO "%s: spi is not 0: %u\n", __FUNCTION__, + x->id.spi); + return -EINVAL; + } + if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) { + printk(KERN_INFO "%s: state's mode is not %u: %u\n", + __FUNCTION__, XFRM_MODE_R
[PATCH 10/20] [PATCH] [IPV6] MIP6: Revert address to send ICMPv6 error.
IPv6 header addresses are replaced in receiving packet with Mobile IPv6 extension headers. To send ICMPv6 error back, original address which is received ones on wire should be used. This function checks such header is included and reverts them. Based on MIPL2 kernel patch. --- net/ipv6/icmp.c | 63 +++ 1 files changed, 63 insertions(+), 0 deletions(-) diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 1044b6f..0812585 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -273,6 +273,67 @@ static int icmpv6_getfrag(void *from, ch return 0; } +#ifdef CONFIG_IPV6_MIP6 +static void mip6_addr_swap(struct sk_buff *skb) +{ + struct ipv6hdr *iph = skb->nh.ipv6h; + struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; + struct in6_addr tmp; + struct ipv6_rt_hdr *rth = NULL; + struct rt2_hdr *rt2h = NULL; + struct destopt_hao *hao = NULL; + unsigned int off; + + if (opt->srcrt) { + rth = (struct ipv6_rt_hdr *)(skb->nh.raw + opt->srcrt); + if (rth->type == IPV6_SRCRT_TYPE_2) + rt2h = (struct rt2_hdr *)rth; + else { + u8 nexthdr = skb->nh.ipv6h->nexthdr; + off = sizeof(struct ipv6hdr); + while (rt2h == NULL && off <= opt->srcrt) { + unsigned len = 0; + u8 *ptr = skb->nh.raw + off; + + switch(nexthdr) { + case IPPROTO_AH: + nexthdr = ptr[0]; + len = (ptr[1] + 2) << 2; + break; + case IPPROTO_ROUTING: + rth = (struct ipv6_rt_hdr *)(skb->nh.raw + off); + if (rth->type == IPV6_SRCRT_TYPE_2) + rt2h = (struct rt2_hdr *)(skb->nh.raw + opt->srcrt); + default: + nexthdr = ptr[0]; + len = (ptr[1] + 1) << 3; + break; + } + off += len; + } + } + if (rt2h != NULL) { + rt2h->rt_hdr.segments_left++; + ipv6_addr_copy(&tmp, &iph->daddr); + ipv6_addr_copy(&iph->daddr, &rt2h->addr); + ipv6_addr_copy(&rt2h->addr, &tmp); + } + } + if (opt->dsthao) { + off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO); + if (likely(off >= 0)) { + hao = (struct destopt_hao *)(skb->nh.raw + off); + ipv6_addr_copy(&tmp, &iph->saddr); + ipv6_addr_copy(&iph->saddr, &hao->addr); + ipv6_addr_copy(&hao->addr, &tmp); + } + } +} +#else +static inline void mip6_addr_swap(struct sk_buff *skb) {} +#endif + + /* * Send an ICMP message in response to a packet in error */ @@ -350,6 +411,8 @@ void icmpv6_send(struct sk_buff *skb, in return; } + mip6_addr_swap(skb); + memset(&fl, 0, sizeof(fl)); fl.proto = IPPROTO_ICMPV6; ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr); -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/20] [PATCH] [IPV6]: Allow to replace skbuff by TLV parser.
In receiving Mobile IPv6 home address option which is a TLV carried by destination options header, kernel will try to mangle source adderss of packet. Think of cloned skbuff it is required to replace it by the parser just like routing header case. This is a framework to achieve that to allow TLV parser to replace inbound skbuff pointer. --- include/net/ipv6.h |2 +- net/ipv6/exthdrs.c | 29 +++-- net/ipv6/ip6_input.c |2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 2e78433..cbe72ea 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -230,7 +230,7 @@ extern int ip6_ra_control(struct sock void (*destructor)(struct sock *)); -extern int ipv6_parse_hopopts(struct sk_buff *skb); +extern int ipv6_parse_hopopts(struct sk_buff **skbp); extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index fbedad9..336992a 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -102,7 +102,7 @@ int ipv6_find_tlv(struct sk_buff *skb, i struct tlvtype_proc { int type; - int (*func)(struct sk_buff *skb, int offset); + int (*func)(struct sk_buff **skbp, int offset); }; /* @@ -111,8 +111,10 @@ struct tlvtype_proc { /* An unknown option is detected, decide what to do */ -static int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff) +static int ip6_tlvopt_unknown(struct sk_buff **skbp, int optoff) { + struct sk_buff *skb = *skbp; + switch ((skb->nh.raw[optoff] & 0xC0) >> 6) { case 0: /* ignore */ return 1; @@ -137,8 +139,9 @@ static int ip6_tlvopt_unknown(struct sk_ /* Parse tlv encoded option header (hop-by-hop or destination) */ -static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb) +static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff **skbp) { + struct sk_buff *skb = *skbp; struct tlvtype_proc *curr; int off = skb->h.raw - skb->nh.raw; int len = ((skb->h.raw[1]+1)<<3); @@ -168,13 +171,13 @@ static int ip6_parse_tlv(struct tlvtype_ /* type specific length/alignment checks will be performed in the func(). */ - if (curr->func(skb, off) == 0) + if (curr->func(skbp, off) == 0) return 0; break; } } if (curr->type < 0) { - if (ip6_tlvopt_unknown(skb, off) == 0) + if (ip6_tlvopt_unknown(skbp, off) == 0) return 0; } break; @@ -213,7 +216,8 @@ static int ipv6_destopt_rcv(struct sk_bu opt->lastopt = skb->h.raw - skb->nh.raw; opt->dst1 = skb->h.raw - skb->nh.raw; - if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { + if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) { + skb = *skbp; skb->h.raw += ((skb->h.raw[1]+1)<<3); opt->nhoff = opt->dst1; return 1; @@ -519,8 +523,10 @@ EXPORT_SYMBOL_GPL(ipv6_invert_rthdr); /* Router Alert as of RFC 2711 */ -static int ipv6_hop_ra(struct sk_buff *skb, int optoff) +static int ipv6_hop_ra(struct sk_buff **skbp, int optoff) { + struct sk_buff *skb = *skbp; + if (skb->nh.raw[optoff+1] == 2) { IP6CB(skb)->ra = optoff; return 1; @@ -533,8 +539,9 @@ static int ipv6_hop_ra(struct sk_buff *s /* Jumbo payload */ -static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff) +static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff) { + struct sk_buff *skb = *skbp; u32 pkt_len; if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { @@ -583,8 +590,9 @@ static struct tlvtype_proc tlvprochopopt { -1, } }; -int ipv6_parse_hopopts(struct sk_buff *skb) +int ipv6_parse_hopopts(struct sk_buff **skbp) { + struct sk_buff *skb = *skbp; struct inet6_skb_parm *opt = IP6CB(skb); /* @@ -600,7 +608,8 @@ int ipv6_parse_hopopts(struct sk_buff *s } opt->hop = sizeof(struct ipv6hdr); - if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { + if (ip6_parse_tlv(tlvprochopopt_lst, skbp)) { + skb = *skbp; skb->h.raw += (skb->h.raw[1]+1)<<3; opt->nhoff = sizeof(struct ipv6hdr);
[PATCH 5/20] [PATCH] [IPV6] MIP6: Add socket option and ancillary data interface of routing header type 2.
Add socket option and ancillary data interface of routing header type 2. Mobile IPv6 application will use this to send binding acknowledgement with the header without relation of confirmed route optimization (binding). Based on MIPL2 kernel patch. --- net/ipv6/datagram.c | 11 +++ net/ipv6/ipv6_sockglue.c | 10 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 99a6eb2..063a74e 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -641,10 +641,13 @@ int datagram_send_ctl(struct msghdr *msg rthdr = (struct ipv6_rt_hdr *)CMSG_DATA(cmsg); - /* -* TYPE 0 -*/ - if (rthdr->type) { + switch (rthdr->type) { + case IPV6_SRCRT_TYPE_0: +#ifdef CONFIG_IPV6_MIP6 + case IPV6_SRCRT_TYPE_2: +#endif + break; + default: err = -EINVAL; goto exit_f; } diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 4c20eeb..68c1512 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -304,8 +304,16 @@ static int do_ipv6_setsockopt(struct soc /* routing header option needs extra check */ if (optname == IPV6_RTHDR && opt->srcrt) { struct ipv6_rt_hdr *rthdr = opt->srcrt; - if (rthdr->type) + switch (rthdr->type) { + case IPV6_SRCRT_TYPE_0: +#ifdef CONFIG_IPV6_MIP6 + case IPV6_SRCRT_TYPE_2: +#endif + break; + default: goto sticky_done; + } + if ((rthdr->hdrlen & 1) || (rthdr->hdrlen >> 1) != rthdr->segments_left) goto sticky_done; -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/20] [PATCH] [IPV6] MIP6: Report to user-space when home address option is rejected.
Report to user-space when home address option is rejected. In receiving this message user-space application will send Mobile IPv6 binding error. It is rate-limited by kernel. Based on MIPL2 kernel patch. --- net/ipv6/mip6.c | 83 +++ 1 files changed, 83 insertions(+), 0 deletions(-) diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index 5721cf8..ebe2f76 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,18 @@ static inline void *mip6_padn(__u8 *data * Destination Options Header */ +struct mip6_report_rate_limiter { + spinlock_t lock; + struct timeval stamp; + int iif; + struct in6_addr src; + struct in6_addr dst; +}; + +static struct mip6_report_rate_limiter mip6_report_rl = { + .lock = SPIN_LOCK_UNLOCKED +}; + static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb) { struct ipv6hdr *iph = skb->nh.ipv6h; @@ -111,6 +124,75 @@ static int mip6_destopt_output(struct xf return 0; } +static inline int mip6_report_rl_allow(struct timeval *stamp, + struct in6_addr *dst, + struct in6_addr *src, int iif) +{ + int allow = 0; + + spin_lock_bh(&mip6_report_rl.lock); + if (mip6_report_rl.stamp.tv_sec != stamp->tv_sec || + mip6_report_rl.stamp.tv_usec != stamp->tv_usec || + mip6_report_rl.iif != iif || + !ipv6_addr_equal(&mip6_report_rl.src, src) || + !ipv6_addr_equal(&mip6_report_rl.dst, dst)) { + mip6_report_rl.stamp.tv_sec = stamp->tv_sec; + mip6_report_rl.stamp.tv_usec = stamp->tv_usec; + mip6_report_rl.iif = iif; + ipv6_addr_copy(&mip6_report_rl.src, src); + ipv6_addr_copy(&mip6_report_rl.dst, dst); + allow = 1; + } + spin_unlock_bh(&mip6_report_rl.lock); + return allow; +} + +static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct flowi *fl) +{ + struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb; + struct destopt_hao *hao = NULL; + struct xfrm_selector sel; + int offset; + struct timeval stamp; + int err = 0; + + if (likely(opt->dsthao)) { + offset = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO); + if (likely(offset >= 0)) + hao = (struct destopt_hao *)(skb->nh.raw + offset); + } + + skb_get_timestamp(skb, &stamp); + + if (!mip6_report_rl_allow(&stamp, &skb->nh.ipv6h->daddr, + hao ? &hao->addr : &skb->nh.ipv6h->saddr, + opt->iif)) + goto out; + + memset(&sel, 0, sizeof(sel)); + memcpy(&sel.daddr, (xfrm_address_t *)&skb->nh.ipv6h->daddr, + sizeof(sel.daddr)); + sel.prefixlen_d = 128; + memcpy(&sel.saddr, (xfrm_address_t *)&skb->nh.ipv6h->saddr, + sizeof(sel.saddr)); + sel.prefixlen_s = 128; + sel.family = AF_INET6; + sel.proto = fl->proto; + sel.dport = xfrm_flowi_dport(fl); + if (sel.dport) + sel.dport_mask = ~((__u16)0); + sel.sport = xfrm_flowi_sport(fl); + if (sel.sport) + sel.sport_mask = ~((__u16)0); + sel.ifindex = fl->oif; + + err = km_report(IPPROTO_DSTOPTS, &sel, + (hao ? (xfrm_address_t *)&hao->addr : NULL)); + + out: + return err; +} + static int mip6_destopt_place_find(struct xfrm_state *x, struct sk_buff *skb, u8 **nexthdr) { @@ -191,6 +273,7 @@ static struct xfrm_type mip6_destopt_typ .destructor = mip6_destopt_destroy, .input = mip6_destopt_input, .output = mip6_destopt_output, + .reject = mip6_destopt_reject, .place_find = mip6_destopt_place_find, .local_addr = mip6_xfrm_addr, }; -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/20] [PATCH] [IPV6] IPSEC: Support sending with Mobile IPv6 extension headers.
Mobile IPv6 defines home address option as an option of destination options header. It is placed before fragment header then ip6_find_1stfragopt() is fixed to know about it. Home address option also carries final source address of the flow, then outbound AH calculation should take care of it like routing header case. Based on MIPL2 kernel patch. --- net/ipv6/ah6.c| 109 + net/ipv6/ip6_output.c | 18 ++-- 2 files changed, 122 insertions(+), 5 deletions(-) diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index dcdd039..af0ed78 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -75,6 +75,68 @@ bad: return 0; } +#ifdef CONFIG_IPV6_MIP6 +/** + * ipv6_rearrange_destopt - rearrange IPv6 destination options header + * @iph: IPv6 header + * @destopt: destionation options header + */ +static void ipv6_rearrange_destopt(struct ipv6hdr *iph, struct ipv6_opt_hdr *destopt) +{ + u8 *opt = (u8 *)destopt; + int len = ipv6_optlen(destopt); + int off = 0; + int optlen = 0; + + off += 2; + len -= 2; + + while (len > 0) { + + switch (opt[off]) { + + case IPV6_TLV_PAD0: + optlen = 1; + break; + default: + if (len < 2) + goto bad; + optlen = opt[off+1]+2; + if (len < optlen) + goto bad; + + /* Rearrange the source address in @iph and the +* addresses in home address option for final source. +* See 11.3.2 of RFC 3775 for details. +*/ + if (opt[off] == IPV6_TLV_HAO) { + struct in6_addr final_addr; + struct destopt_hao *hao; + + hao = (struct destopt_hao *)&opt[off]; + if (hao->length != sizeof(hao->addr)) { + if (net_ratelimit()) + printk(KERN_WARNING "destopt hao: invalid header length: %u\n", hao->length); + goto bad; + } + ipv6_addr_copy(&final_addr, &hao->addr); + ipv6_addr_copy(&hao->addr, &iph->saddr); + ipv6_addr_copy(&iph->saddr, &final_addr); + } + break; + } + + off += optlen; + len -= optlen; + } + if (len == 0) + return; + +bad: + return; +} +#endif + /** * ipv6_rearrange_rthdr - rearrange IPv6 routing header * @iph: IPv6 header @@ -114,7 +176,11 @@ static void ipv6_rearrange_rthdr(struct ipv6_addr_copy(&iph->daddr, &final_addr); } +#ifdef CONFIG_IPV6_MIP6 +static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len, int dir) +#else static int ipv6_clear_mutable_options(struct ipv6hdr *iph, int len) +#endif { union { struct ipv6hdr *iph; @@ -129,6 +195,28 @@ static int ipv6_clear_mutable_options(st while (exthdr.raw < end) { switch (nexthdr) { +#ifdef CONFIG_IPV6_MIP6 + case NEXTHDR_HOP: + if (!zero_out_mutable_opts(exthdr.opth)) { + LIMIT_NETDEBUG( + KERN_WARNING "overrun %sopts\n", + nexthdr == NEXTHDR_HOP ? + "hop" : "dest"); + return -EINVAL; + } + break; + case NEXTHDR_DEST: + if (dir == XFRM_POLICY_OUT) + ipv6_rearrange_destopt(iph, exthdr.opth); + if (!zero_out_mutable_opts(exthdr.opth)) { + LIMIT_NETDEBUG( + KERN_WARNING "overrun %sopts\n", + nexthdr == NEXTHDR_HOP ? + "hop" : "dest"); + return -EINVAL; + } + break; +#else case NEXTHDR_HOP: case NEXTHDR_DEST: if (!zero_out_mutable_opts(exthdr.opth)) { @@ -139,6 +227,7 @@ static int ipv6_clear_mutable_options(st return -EINVAL; } break; +#endif case NEXTHDR_ROUTING: ipv6_rearrange_rthdr(iph, exthdr.rth); @@ -165,6 +254,9 @@ static int ah6_output(struct xfrm_state u8 nexthdr; char tmp_base[8]; str
[PATCH 3/20] [PATCH] [IPV6] MIP6: Add routing header type 2 definition.
Add routing header type 2 definition for Mobile IPv6. Based on MIPL2 kernel patch. --- include/linux/ipv6.h | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 1263d8c..9152d4b 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -30,6 +30,7 @@ struct in6_ifreq { #define IPV6_SRCRT_STRICT 0x01/* this hop must be a neighbor */ #define IPV6_SRCRT_TYPE_0 0 /* IPv6 type 0 Routing Header */ +#define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */ /* * routing header @@ -74,6 +75,18 @@ struct rt0_hdr { #define rt0_type rt_hdr.type }; +/* + * routing header type 2 + */ + +struct rt2_hdr { + struct ipv6_rt_hdr rt_hdr; + __u32 reserved; + struct in6_addr addr; + +#define rt2_type rt_hdr.type +}; + struct ipv6_auth_hdr { __u8 nexthdr; __u8 hdrlen; /* This one is measured in 32 bit units! */ -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/20] [PATCH] [IPV6]: Add Kconfig to enable Mobile IPv6.
Based on MIPL2 kernel patch. --- net/ipv6/Kconfig |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index f8a107a..06b1c3a 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -115,3 +115,12 @@ config IPV6_TUNNEL If unsure, say N. +config IPV6_MIP6 + bool "IPv6: Mobility (EXPERIMENTAL)" + depends on IPV6 && EXPERIMENTAL + select XFRM + select XFRM_ADVANCED + ---help--- + Support for IPv6 Mobility described in RFC 3775. + + If unsure, say N. -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/20][IPV6/XFRM] MIPv6 CN (part B)
Here is Part B patches, following this mail. Part B is also available as mip6cn-20060716-review branch at: git://git.skbuff.net:9419/gitroot/nakam/linux-2.6-mip6cn This tree includes part A, then it has all patches about "Advanced XFRM for CN". > Please see patches about "Avanced XFRM for CN", following this mail. > These are just for review, and it is against 2.6.17. > > "Avanced XFRM for CN" tree is consists of: > > A. XFRM extension for route optimization > B. IPv6 extension headers: > new type (2) of routing header > new TLV option for destination options header: home address option > new header for signaling: mobility header > [snip] >> 3. Advanced XFRM for CN >> "Route optimization" defined MIPv6 specification >> is designed as XFRM extension. IPv6 extension headers >> handling is included, too. >> This feature is required by all MIPv6 nodes(CN, MN, HA) then it can >> be said MIPv6 platform. Thanks, -- Masahide NAKAMURA - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 19/23] [PATCH] [XFRM] POLICY: Add Kconfig to support sub policy.
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig index 50f2fb3..9d28e88 100644 --- a/net/xfrm/Kconfig +++ b/net/xfrm/Kconfig @@ -22,6 +22,16 @@ config XFRM_ADVANCED If unsure, say N. +config XFRM_SUB_POLICY + bool "Transformation sub policy support (EXPERIMENTAL)" + depends on XFRM && EXPERIMENTAL + ---help--- + Support sub policy for developers. By using sub policy with main + one, two policies can be applied to the same packet at once. + Policy which lives shorter time in kernel should be a sub. + + If unsure, say N. + config NET_KEY tristate "PF_KEY sockets" select XFRM -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 17/23] [PATCH] [XFRM]: Introduce XFRM_MSG_REPORT.
XFRM_MSG_REPORT is a message as notification of state protocol and selector from kernel to user-space. Mobile IPv6 will use it when inbound reject is occurred at route optimization to make user-space know a binding error requirement. Based on MIPL2 kernel patch. --- include/linux/xfrm.h | 15 ++ include/net/xfrm.h| 11 ++ net/xfrm/xfrm_state.c | 21 net/xfrm/xfrm_user.c | 52 + 4 files changed, 99 insertions(+), 0 deletions(-) diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 597a7c7..84a3e76 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -160,6 +160,10 @@ #define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FL #define XFRM_MSG_NEWAE XFRM_MSG_NEWAE XFRM_MSG_GETAE, #define XFRM_MSG_GETAE XFRM_MSG_GETAE + + XFRM_MSG_REPORT, +#define XFRM_MSG_REPORT XFRM_MSG_REPORT + __XFRM_MSG_MAX }; #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) @@ -325,12 +329,21 @@ struct xfrm_usersa_flush { __u8proto; }; +/* + * This notifies flow information to the user space with carrying XFRMA_ADDR. + */ +struct xfrm_user_report { + __u8proto; + struct xfrm_selectorsel; +}; + #ifndef __KERNEL__ /* backwards compatibility for userspace */ #define XFRMGRP_ACQUIRE1 #define XFRMGRP_EXPIRE 2 #define XFRMGRP_SA 4 #define XFRMGRP_POLICY 8 +#define XFRMGRP_REPORT 0x20 #endif enum xfrm_nlgroups { @@ -346,6 +359,8 @@ #define XFRMNLGRP_SAXFRMNLGRP_SA #define XFRMNLGRP_POLICY XFRMNLGRP_POLICY XFRMNLGRP_AEVENTS, #define XFRMNLGRP_AEVENTS XFRMNLGRP_AEVENTS + XFRMNLGRP_REPORT, +#define XFRMNLGRP_REPORT XFRMNLGRP_REPORT __XFRMNLGRP_MAX }; #define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 0b8edad..05d4257 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -383,6 +383,9 @@ struct xfrm_mgr struct xfrm_policy *(*compile_policy)(u16 family, int opt, u8 *data, int len, int *dir); int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c); +#ifdef CONFIG_XFRM_ADVANCED + int (*report)(__u8 proto, struct xfrm_selector *sel, void *arg); +#endif }; extern int xfrm_register_km(struct xfrm_mgr *km); @@ -1042,6 +1045,14 @@ extern wait_queue_head_t km_waitq; extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid); +#ifdef CONFIG_XFRM_ADVANCED +extern int km_report(__u8 proto, struct xfrm_selector *sel, void *arg); +#else +static inline int km_report(__u8 proto, struct xfrm_selector *sel, void *arg) +{ + return -ENOSYS; +} +#endif extern void xfrm_input_init(void); extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 1bdeecf..0c74e7c 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1077,6 +1077,27 @@ void km_policy_expired(struct xfrm_polic } EXPORT_SYMBOL(km_policy_expired); +#ifdef CONFIG_XFRM_ADVANCED +int km_report(__u8 proto, struct xfrm_selector *sel, void *arg) +{ + int err = -EINVAL; + int ret; + struct xfrm_mgr *km; + + read_lock(&xfrm_km_lock); + list_for_each_entry(km, &xfrm_km_list, list) { + if (km->report) { + ret = km->report(proto, sel, arg); + if (!ret) + err = ret; + } + } + read_unlock(&xfrm_km_lock); + return err; +} +EXPORT_SYMBOL(km_report); +#endif + int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen) { int err; diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index a91367d..8d7bf0a 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1443,6 +1443,9 @@ static const int xfrm_msg_min[XFRM_NR_MS [XFRM_MSG_FLUSHPOLICY - XFRM_MSG_BASE] = NLMSG_LENGTH(0), [XFRM_MSG_NEWAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id), [XFRM_MSG_GETAE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_aevent_id), +#ifdef CONFIG_XFRM_ADVANCED + [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report), +#endif }; #undef XMSGSIZE @@ -2001,12 +2004,61 @@ static int xfrm_send_policy_notify(struc } +#ifdef CONFIG_XFRM_ADVANCED +static int build_report(struct sk_buff *skb, __u8 proto, + struct xfrm_selector *sel, void *arg) +{ + xfrm_address_t *addr = (xfrm_address_t *)arg; + struct xfrm_user_report *ur; + struct nlmsghdr *nlh; + unsigned char *b = skb->tail; + +
[PATCH 16/23] [PATCH] [XFRM]: Rename secpath_has_tunnel to secpath_has_nontransport.
On current kernel inbound transformation state is allowed transport and disallowed tunnel mode when mismatch is occurred between tempates and states. As the result of adding two more modes by Mobile IPv6, this function name is misleading. Inbound transformation can allow only transport mode when mismatch is occurred between template and secpath. Based on MIPL2 kernel patch. --- net/xfrm/xfrm_policy.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index e3c71b6..7368f8a 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1002,7 +1002,7 @@ xfrm_decode_session(struct sk_buff *skb, } EXPORT_SYMBOL(xfrm_decode_session); -static inline int secpath_has_tunnel(struct sec_path *sp, int k, int *idxp) +static inline int secpath_has_nontransport(struct sec_path *sp, int k, int *idxp) { for (; k < sp->len; k++) { if (sp->xvec[k]->props.mode != XFRM_MODE_TRANSPORT) { @@ -1055,7 +1055,7 @@ #endif xfrm_policy_lookup); if (!pol) { - if (skb->sp && secpath_has_tunnel(skb->sp, 0, xerr_idxp)) { + if (skb->sp && secpath_has_nontransport(skb->sp, 0, xerr_idxp)) { xfrm_secpath_reject(xerr_idx, skb, &fl); return 0; } @@ -1087,7 +1087,7 @@ #endif } } - if (secpath_has_tunnel(sp, k, xerr_idxp)) + if (secpath_has_nontransport(sp, k, xerr_idxp)) goto reject; xfrm_pol_put(pol); -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 12/23] [PATCH] [XFRM] STATE: Introduce care-of address.
Care-of address is carried by state as a transformation option like IPsec encryption/authentication algorithm. Based on MIPL2 kernel patch. --- include/linux/xfrm.h |1 + include/net/xfrm.h|5 + net/xfrm/xfrm_state.c | 10 + net/xfrm/xfrm_user.c | 53 - 4 files changed, 68 insertions(+), 1 deletions(-) diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 47e39f6..597a7c7 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -235,6 +235,7 @@ enum xfrm_attr_type_t { XFRMA_REPLAY_VAL, XFRMA_REPLAY_THRESH, XFRMA_ETIMER_THRESH, + XFRMA_ADDR, /* xfrm_address_t */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index f551bc6..de62a8f 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -135,6 +135,11 @@ #endif /* Data for encapsulator */ struct xfrm_encap_tmpl *encap; +#ifdef CONFIG_XFRM_ADVANCED + /* Data for care-of address */ + xfrm_address_t *coaddr; +#endif + /* IPComp needs an IPIP tunnel for handling uncompressed packets */ struct xfrm_state *tunnel; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 60def7a..1bdeecf 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -80,6 +80,9 @@ static void xfrm_state_gc_destroy(struct kfree(x->ealg); kfree(x->calg); kfree(x->encap); +#ifdef CONFIG_XFRM_ADVANCED + kfree(x->coaddr); +#endif if (x->type) { x->type->destructor(x); xfrm_put_type(x->type); @@ -619,6 +622,13 @@ out: if (likely(x1->km.state == XFRM_STATE_VALID)) { if (x->encap && x1->encap) memcpy(x1->encap, x->encap, sizeof(*x1->encap)); +#ifdef CONFIG_XFRM_ADVANCED + if (x->coaddr && x1->coaddr) { + memcpy(x1->coaddr, x->coaddr, sizeof(*x1->coaddr)); + } + if (!use_spi && memcmp(&x1->sel, &x->sel, sizeof(x1->sel))) + memcpy(&x1->sel, &x->sel, sizeof(x1->sel)); +#endif memcpy(&x1->lft, &x->lft, sizeof(x1->lft)); x1->km.dying = 0; diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 85051a2..13fe172 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -110,6 +110,21 @@ static inline int verify_sec_ctx_len(str return 0; } +#ifdef CONFIG_XFRM_ADVANCED +static int verify_one_addr(struct rtattr **xfrma) +{ + struct rtattr *rt = xfrma[XFRMA_ADDR - 1]; + xfrm_address_t *addr; + + if (!rt) + return 0; + + if ((rt->rta_len - sizeof(*rt)) < sizeof(*addr)) + return -EINVAL; + + return 0; +} +#endif static int verify_newsa_info(struct xfrm_usersa_info *p, struct rtattr **xfrma) @@ -170,11 +185,18 @@ #endif goto out; if ((err = verify_sec_ctx_len(xfrma))) goto out; +#ifdef CONFIG_XFRM_ADVANCED + if ((err = verify_one_addr(xfrma))) + goto out; +#endif err = -EINVAL; switch (p->mode) { case XFRM_MODE_TRANSPORT: case XFRM_MODE_TUNNEL: +#ifdef CONFIG_XFRM_ADVANCED + case XFRM_MODE_ROUTEOPTIMIZATION: +#endif break; default: @@ -258,6 +280,26 @@ static int attach_sec_ctx(struct xfrm_st return security_xfrm_state_alloc(x, uctx); } +#ifdef CONFIG_XFRM_ADVANCED +static int attach_one_addr(xfrm_address_t **addrpp, struct rtattr *u_arg) +{ + struct rtattr *rta = u_arg; + xfrm_address_t *p, *uaddrp; + + if (!rta) + return 0; + + uaddrp = RTA_DATA(rta); + p = kmalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + memcpy(p, uaddrp, sizeof(*p)); + *addrpp = p; + return 0; +} +#endif + static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p) { memcpy(&x->id, &p->id, sizeof(x->id)); @@ -347,7 +389,10 @@ static struct xfrm_state *xfrm_state_con goto error; if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1]))) goto error; - +#ifdef CONFIG_XFRM_ADVANCED + if ((err = attach_one_addr(&x->coaddr, xfrma[XFRMA_ADDR-1]))) + goto error; +#endif err = xfrm_init_state(x); if (err) goto error; @@ -526,6 +571,12 @@ static int dump_one_state(struct xfrm_st uctx->ctx_len = x->security->ctx_len; memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len); } + +#ifdef CONFIG_XFRM_ADVANCED + if (x->coaddr) + RTA_PUT(skb, XFRMA_ADDR, sizeof(*x->coaddr), x->coaddr); +#endif + nlh->nlmsg_len = skb->tail - b; out: sp->this_idx++; -- 1.4.1 - To unsubscribe from this list: send
[PATCH 9/23] [PATCH] [XFRM] STATE: Support non-fragment outbound transformation headers.
For originated outbound IPv6 packets which will fragment, ip6_append_data() should know length of extension headers before sending them and the length is carried by dst_entry. IPv6 IPsec headers fragment then transformation was designed to place all headers after fragment header. OTOH Mobile IPv6 extension headers do not fragment then it is a good idea to make dst_entry have non-fragment length to tell it to ip6_append_data(). --- include/net/dst.h |1 + include/net/xfrm.h |2 ++ net/ipv4/xfrm4_policy.c |1 + net/ipv6/ip6_output.c |2 +- net/ipv6/xfrm6_policy.c | 12 ++-- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/net/dst.h b/include/net/dst.h index 5161e89..1ac2ee0 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -55,6 +55,7 @@ #define DST_BALANCED0x10 unsigned long expires; unsigned short header_len; /* more space at head required */ + unsigned short nfheader_len; /* more non-fragment space at head required */ unsigned short trailer_len;/* space to reserve at tail */ u32 metrics[RTAX_MAX]; diff --git a/include/net/xfrm.h b/include/net/xfrm.h index e14ae3c..46f8616 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -265,6 +265,8 @@ struct xfrm_type char*description; struct module *owner; __u8proto; + __u8flags; +#define XFRM_TYPE_NON_FRAGMENT 1 int (*init_state)(struct xfrm_state *x); void(*destructor)(struct xfrm_state *); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index bf77489..03f17a0 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -138,6 +138,7 @@ __xfrm4_bundle_create(struct xfrm_policy dst_prev->flags|= DST_HOST; dst_prev->lastuse = jiffies; dst_prev->header_len= header_len; + dst_prev->nfheader_len = 0; dst_prev->trailer_len = trailer_len; memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics)); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index e460489..2d9ea9b 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -915,7 +915,7 @@ int ip6_append_data(struct sock *sk, int hh_len = LL_RESERVED_SPACE(rt->u.dst.dev); - fragheaderlen = sizeof(struct ipv6hdr) + (opt ? opt->opt_nflen : 0); + fragheaderlen = sizeof(struct ipv6hdr) + rt->u.dst.nfheader_len + (opt ? opt->opt_nflen : 0); maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 28bc272..eaa1b0d 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -86,6 +86,7 @@ __xfrm6_bundle_create(struct xfrm_policy int i; int err = 0; int header_len = 0; + int nfheader_len = 0; int trailer_len = 0; dst = dst_prev = NULL; @@ -126,7 +127,10 @@ __xfrm6_bundle_create(struct xfrm_policy (struct in6_addr*)&xfrm[i]->props.saddr; tunnel = 1; } - header_len += xfrm[i]->props.header_len; + if (xfrm[i]->type->flags & XFRM_TYPE_NON_FRAGMENT) + nfheader_len += xfrm[i]->props.header_len; + else + header_len += xfrm[i]->props.header_len; trailer_len += xfrm[i]->props.trailer_len; if (tunnel) { @@ -161,6 +165,7 @@ __xfrm6_bundle_create(struct xfrm_policy dst_prev->flags|= DST_HOST; dst_prev->lastuse = jiffies; dst_prev->header_len= header_len; + dst_prev->nfheader_len = nfheader_len; dst_prev->trailer_len = trailer_len; memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics)); @@ -179,7 +184,10 @@ __xfrm6_bundle_create(struct xfrm_policy x->u.rt6.rt6i_src = rt0->rt6i_src; x->u.rt6.rt6i_idev = rt0->rt6i_idev; in6_dev_hold(rt0->rt6i_idev); - header_len -= x->u.dst.xfrm->props.header_len; + if (dst_prev->xfrm->type->flags & XFRM_TYPE_NON_FRAGMENT) + nfheader_len -= x->u.dst.xfrm->props.header_len; + else + header_len -= x->u.dst.xfrm->props.header_len; trailer_len -= x->u.dst.xfrm->props.trailer_len; } -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/m
[PATCH 6/23] [PATCH] [XFRM] STATE: Search by address using source address list.
This is a support to search transformation states by its addresses by using source address list. For Mobile IPv6 usage. Based on MIPL2 kernel patch. --- include/net/xfrm.h | 11 +++ net/ipv4/xfrm4_state.c | 13 + net/ipv6/xfrm6_state.c | 25 net/xfrm/xfrm_state.c | 49 +++- net/xfrm/xfrm_user.c | 13 +++-- 5 files changed, 104 insertions(+), 7 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 75649da..aaef1c4 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -247,6 +247,9 @@ #endif struct xfrm_tmpl *tmpl, xfrm_address_t *daddr, xfrm_address_t *saddr); struct xfrm_state *(*state_lookup)(xfrm_address_t *daddr, u32 spi, u8 proto); +#ifdef CONFIG_XFRM_ADVANCED + struct xfrm_state *(*state_lookup_byaddr)(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto); +#endif struct xfrm_state *(*find_acq)(u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create); @@ -930,6 +933,14 @@ extern void xfrm_state_insert(struct xfr extern int xfrm_state_add(struct xfrm_state *x); extern int xfrm_state_update(struct xfrm_state *x); extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family); +#ifdef CONFIG_XFRM_ADVANCED +extern struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family); +#else +static inline struct xfrm_state *xfrm_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto, unsigned short family) +{ + return NULL; +} +#endif extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); extern int xfrm_state_delete(struct xfrm_state *x); extern void xfrm_state_flush(u8 proto); diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 6de2ce0..8b44a75 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c @@ -80,6 +80,16 @@ __xfrm4_state_lookup(xfrm_address_t *dad return NULL; } +#ifdef CONFIG_XFRM_ADVANCED +/* placeholder until ipv4's code is written */ +static struct xfrm_state * +__xfrm4_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, + u8 proto) +{ + return NULL; +} +#endif + static struct xfrm_state * __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, @@ -140,6 +150,9 @@ static struct xfrm_state_afinfo xfrm4_st .init_flags = xfrm4_init_flags, .init_tempsel = __xfrm4_init_tempsel, .state_lookup = __xfrm4_state_lookup, +#ifdef CONFIG_XFRM_ADVANCED + .state_lookup_byaddr= __xfrm4_state_lookup_byaddr, +#endif .find_acq = __xfrm4_find_acq, }; diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 00b6c17..d141030 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c @@ -63,6 +63,28 @@ __xfrm6_init_tempsel(struct xfrm_state * x->props.family = AF_INET6; } +#ifdef CONFIG_XFRM_ADVANCED +static struct xfrm_state * +__xfrm6_state_lookup_byaddr(xfrm_address_t *daddr, xfrm_address_t *saddr, + u8 proto) +{ + struct xfrm_state *x = NULL; + unsigned h; + + h = __xfrm6_src_hash(saddr); + list_for_each_entry(x, xfrm6_state_afinfo.state_bysrc+h, bysrc) { + if (x->props.family == AF_INET6 && + ipv6_addr_equal((struct in6_addr *)daddr, (struct in6_addr *)x->id.daddr.a6) && + ipv6_addr_equal((struct in6_addr *)saddr, (struct in6_addr *)x->props.saddr.a6) && + proto == x->id.proto) { + xfrm_state_hold(x); + return x; + } + } + return NULL; +} +#endif + static struct xfrm_state * __xfrm6_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto) { @@ -143,6 +165,9 @@ static struct xfrm_state_afinfo xfrm6_st .lock = RW_LOCK_UNLOCKED, .init_tempsel = __xfrm6_init_tempsel, .state_lookup = __xfrm6_state_lookup, +#ifdef CONFIG_XFRM_ADVANCED + .state_lookup_byaddr= __xfrm6_state_lookup_byaddr, +#endif .find_acq = __xfrm6_find_acq, }; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 1942bb1..1eedb85 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -501,6 +501,11 @@ int xfrm_state_add(struct xfrm_state *x) struct xfrm_state *x1; int family; int err; +#ifdef CONFIG_XFRM_ADVANCED + int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); +#else + int use_spi = 1; +#endif fa
[PATCH 7/23] [PATCH] [XFRM] STATE: Add a hook to find where to be inserted header in outbound.
On current kernel, ip6_find_1stfragopt() is used by IPv6 IPsec to find where to be inserted header in outbound. (BTW, no usage may be needed for IPv4 case.) Mobile IPv6 requires other logic for routing header and destination options header respectively. Based on MIPL2 kernel patch. --- include/net/xfrm.h |1 + net/ipv6/xfrm6_output.c |5 - 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index aaef1c4..bcda8c0 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -270,6 +270,7 @@ struct xfrm_type void(*destructor)(struct xfrm_state *); int (*input)(struct xfrm_state *, struct sk_buff *skb); int (*output)(struct xfrm_state *, struct sk_buff *pskb); + int (*place_find)(struct xfrm_state *, struct sk_buff *, u8 **); /* Estimate maximal size of result of transformation of a dgram */ u32 (*get_max_size)(struct xfrm_state *, int size); }; diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 2736a54..8792b5c 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -48,7 +48,10 @@ static void xfrm6_encap(struct sk_buff * u8 *prevhdr; int hdr_len; - hdr_len = ip6_find_1stfragopt(skb, &prevhdr); + if (x->type->place_find) + hdr_len = x->type->place_find(x, skb, &prevhdr); + else + hdr_len = ip6_find_1stfragopt(skb, &prevhdr); skb->nh.raw = prevhdr - x->props.header_len; skb->h.raw = skb->data + hdr_len; memmove(skb->data, iph, hdr_len); -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/23] [PATCH] [XFRM]: Trace which secpath state is reject factor.
For Mobile IPv6 usage, it is required to trace which secpath state is reject factor in order to notify it to user space (to know the address which cannot be used route optimized communication). Based on MIPL2 kernel patch. --- include/net/xfrm.h |3 ++ net/xfrm/xfrm_policy.c | 67 +++- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 46f8616..8dcf6cd 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -272,6 +272,9 @@ #define XFRM_TYPE_NON_FRAGMENT 1 void(*destructor)(struct xfrm_state *); int (*input)(struct xfrm_state *, struct sk_buff *skb); int (*output)(struct xfrm_state *, struct sk_buff *pskb); +#ifdef CONFIG_XFRM_ADVANCED + int (*reject)(struct xfrm_state *, struct sk_buff *skb, struct flowi *); +#endif int (*place_find)(struct xfrm_state *, struct sk_buff *, u8 **); xfrm_address_t *(*local_addr)(struct xfrm_state *, xfrm_address_t *); xfrm_address_t *(*remote_addr)(struct xfrm_state *, xfrm_address_t *); diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index d143381..1663ffa 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -911,6 +911,31 @@ error: } EXPORT_SYMBOL(xfrm_lookup); +#ifdef CONFIG_XFRM_ADVANCED +static inline int +xfrm_secpath_reject(int idx, struct sk_buff *skb, struct flowi *fl) +{ + struct xfrm_state *x; + int err; + + if (!skb->sp || idx < 0 || idx >= skb->sp->len) + return 0; + x = skb->sp->xvec[idx]; + if (!x->type->reject) + return 0; + xfrm_state_hold(x); + err = x->type->reject(x, skb, fl); + xfrm_state_put(x); + return err; +} +#else +static inline int +xfrm_secpath_reject(int idx, struct sk_buff *skb, struct flowi *fl) +{ + return 0; +} +#endif + /* When skb is transformed back to its "native" form, we have to * check policy restrictions. At the moment we make this in maximally * stupid way. Shame on me. :-) Of course, connected sockets must @@ -932,6 +957,13 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, st xfrm_state_addr_cmp(tmpl, x, family)); } +/* + * 0 or more than 0 is returned when validation is succeeded (either bypass + * because of optional transport mode, or next index of the mathced secpath + * state with the template. + * -1 is returned when no matching template is found. + * Otherwise "-2 - errored_index" is returned. + */ static inline int xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start, unsigned short family) @@ -946,8 +978,11 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, s for (; idx < sp->len; idx++) { if (xfrm_state_ok(tmpl, sp->xvec[idx], family)) return ++idx; - if (sp->xvec[idx]->props.mode != XFRM_MODE_TRANSPORT) + if (sp->xvec[idx]->props.mode != XFRM_MODE_TRANSPORT) { + if (start == -1) + start = -2-idx; break; + } } return start; } @@ -966,11 +1001,14 @@ xfrm_decode_session(struct sk_buff *skb, } EXPORT_SYMBOL(xfrm_decode_session); -static inline int secpath_has_tunnel(struct sec_path *sp, int k) +static inline int secpath_has_tunnel(struct sec_path *sp, int k, int *idxp) { for (; k < sp->len; k++) { - if (sp->xvec[k]->props.mode != XFRM_MODE_TRANSPORT) + if (sp->xvec[k]->props.mode != XFRM_MODE_TRANSPORT) { + if (idxp) + *idxp = k; return 1; + } } return 0; @@ -983,6 +1021,12 @@ int __xfrm_policy_check(struct sock *sk, struct flowi fl; u8 fl_dir = policy_to_flow_dir(dir); u32 sk_sid; + int xerr_idx = -1; +#ifdef CONFIG_XFRM_ADVANCED + int *xerr_idxp = &xerr_idx; +#else + int *xerr_idxp = NULL; +#endif if (xfrm_decode_session(skb, &fl, family) < 0) return 0; @@ -1009,8 +1053,13 @@ int __xfrm_policy_check(struct sock *sk, pol = flow_cache_lookup(&fl, sk_sid, family, fl_dir, xfrm_policy_lookup); - if (!pol) - return !skb->sp || !secpath_has_tunnel(skb->sp, 0); + if (!pol) { + if (skb->sp && secpath_has_tunnel(skb->sp, 0, xerr_idxp)) { + xfrm_secpath_reject(xerr_idx, skb, &fl); + return 0; + } + return 1; + } pol->curlft.use_time = (unsigned long)xtime.tv_sec; @@ -1030,11 +1079,14 @@ int __xfrm_policy_check(struct sock *sk, */ for (i = pol->xfrm_nr-1, k = 0; i >= 0; i
[PATCH 22/23] [PATCH] [XFRM] POLICY: Support netlink socket interface for sub policy.
Sub policy can be used through netlink socket. (PF_KEY uses main only and it is TODO to support sub.) --- include/linux/xfrm.h |6 + include/net/xfrm.h |1 + net/key/af_key.c | 13 +++ net/xfrm/xfrm_user.c | 60 +++--- 4 files changed, 66 insertions(+), 14 deletions(-) diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 901bb65..68d3443 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -303,12 +303,14 @@ #define XFRM_POLICY_BLOCK 1 __u8flags; #define XFRM_POLICY_LOCALOK1 /* Allow user to override global policy */ __u8share; + __u8type; }; struct xfrm_userpolicy_id { struct xfrm_selectorsel; __u32 index; __u8dir; + __u8type; }; struct xfrm_user_acquire { @@ -336,6 +338,10 @@ struct xfrm_usersa_flush { __u8proto; }; +struct xfrm_userpolicy_flush { + __u8type; +}; + /* * This notifies flow information to the user space with carrying XFRMA_ADDR. */ diff --git a/include/net/xfrm.h b/include/net/xfrm.h index c1cc2f5..0d14b1f 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -202,6 +202,7 @@ struct km_event u32 proto; u32 byid; u32 aevent; + u32 type; } data; u32 seq; diff --git a/net/key/af_key.c b/net/key/af_key.c index ed2d712..2bc9665 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -1730,7 +1730,8 @@ static u32 gen_reqid(void) ++reqid; if (reqid == 0) reqid = IPSEC_MANUAL_REQID_MAX+1; - if (xfrm_policy_walk(check_reqid, (void*)&reqid) != -EEXIST) + if (xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, check_reqid, +(void*)&reqid) != -EEXIST) return reqid; } while (reqid != start); return 0; @@ -2267,7 +2268,8 @@ static int pfkey_spddelete(struct sock * return err; } - xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel, tmp.security, 1); + xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1, + &sel, tmp.security, 1); security_xfrm_policy_free(&tmp); if (xp == NULL) return -ENOENT; @@ -2326,7 +2328,7 @@ static int pfkey_spdget(struct sock *sk, if (dir >= XFRM_POLICY_MAX) return -EINVAL; - xp = xfrm_policy_byid(dir, pol->sadb_x_policy_id, + xp = xfrm_policy_byid(XFRM_POLICY_TYPE_MAIN, dir, pol->sadb_x_policy_id, hdr->sadb_msg_type == SADB_X_SPDDELETE2); if (xp == NULL) return -ENOENT; @@ -2374,7 +2376,7 @@ static int pfkey_spddump(struct sock *sk { struct pfkey_dump_data data = { .skb = skb, .hdr = hdr, .sk = sk }; - return xfrm_policy_walk(dump_sp, &data); + return xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_sp, &data); } static int key_notify_policy_flush(struct km_event *c) @@ -2401,7 +2403,8 @@ static int pfkey_spdflush(struct sock *s { struct km_event c; - xfrm_policy_flush(); + xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN); + c.data.type = XFRM_POLICY_TYPE_MAIN; c.event = XFRM_MSG_FLUSHPOLICY; c.pid = hdr->sadb_msg_pid; c.seq = hdr->sadb_msg_seq; diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 8d7bf0a..cf62208 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -754,8 +754,26 @@ static int verify_policy_dir(__u8 dir) return 0; } +static int verify_policy_type(__u8 type) +{ + switch (type) { + case XFRM_POLICY_TYPE_MAIN: +#ifdef CONFIG_XFRM_SUB_POLICY + case XFRM_POLICY_TYPE_SUB: +#endif + break; + + default: + return -EINVAL; + }; + + return 0; +} + static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) { + int err; + switch (p->share) { case XFRM_SHARE_ANY: case XFRM_SHARE_SESSION: @@ -791,6 +809,10 @@ #endif return -EINVAL; }; + err = verify_policy_type(p->type); + if (err) + return err; + return verify_policy_dir(p->dir); } @@ -857,6 +879,7 @@ static void copy_from_user_policy(struct xp->flags = p->flags; xp->family = p->sel.family; /* XXX xp->share = p->share; */ + xp->type = p->type; } static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p, int dir) @@ -871,6 +894,7 @@ static void copy_to_user_policy(struct x p->action = xp->action; p->flags =
[PATCH 23/23] [PATCH] [XFRM] IPV6: Add sort functions to combine templates/states for IPsec.
Add sort functions to combine templates/states for IPsec. Think of outbound transformation order we should be careful with transport AH which must be the last of all transport ones. --- net/ipv6/xfrm6_state.c | 101 1 files changed, 101 insertions(+), 0 deletions(-) diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index d141030..1a5cc65 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c @@ -160,6 +160,103 @@ #endif return x0; } +#ifdef CONFIG_XFRM_SUB_POLICY +static int +__xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n) +{ + int i; + int j = 0; + + /* Rule 1: select IPsec transport except AH */ + for (i = 0; i < n; i++) { + if (src[i]->props.mode == XFRM_MODE_TRANSPORT && + src[i]->id.proto != IPPROTO_AH) { + dst[j++] = src[i]; + src[i] = NULL; + } + } + if (j == n) + goto end; + + /* XXX: Rule 2: select MIPv6 RO or inbound trigger */ + + /* Rule 3: select IPsec transport AH */ + for (i = 0; i < n; i++) { + if (src[i] && + src[i]->props.mode == XFRM_MODE_TRANSPORT && + src[i]->id.proto == IPPROTO_AH) { + dst[j++] = src[i]; + src[i] = NULL; + } + } + if (j == n) + goto end; + + /* Rule 4: select IPsec tunnel */ + for (i = 0; i < n; i++) { + if (src[i] && + src[i]->props.mode == XFRM_MODE_TUNNEL) { + dst[j++] = src[i]; + src[i] = NULL; + } + } + if (likely(j == n)) + goto end; + + /* Final rule */ + for (i = 0; i < n; i++) { + if (src[i]) { + dst[j++] = src[i]; + src[i] = NULL; + } + } + + end: + return 0; +} + +static int +__xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n) +{ + int i; + int j = 0; + + /* Rule 1: select IPsec transport */ + for (i = 0; i < n; i++) { + if (src[i]->mode == XFRM_MODE_TRANSPORT) { + dst[j++] = src[i]; + src[i] = NULL; + } + } + if (j == n) + goto end; + + /* XXX: Rule 2: select MIPv6 RO or inbound trigger */ + + /* Rule 3: select IPsec tunnel */ + for (i = 0; i < n; i++) { + if (src[i] && + src[i]->mode == XFRM_MODE_TUNNEL) { + dst[j++] = src[i]; + src[i] = NULL; + } + } + if (likely(j == n)) + goto end; + + /* Final rule */ + for (i = 0; i < n; i++) { + if (src[i]) { + dst[j++] = src[i]; + src[i] = NULL; + } + } + + end: + return 0; +} +#endif + static struct xfrm_state_afinfo xfrm6_state_afinfo = { .family = AF_INET6, .lock = RW_LOCK_UNLOCKED, @@ -169,6 +266,10 @@ #ifdef CONFIG_XFRM_ADVANCED .state_lookup_byaddr= __xfrm6_state_lookup_byaddr, #endif .find_acq = __xfrm6_find_acq, +#ifdef CONFIG_XFRM_SUB_POLICY + .tmpl_sort = __xfrm6_tmpl_sort, + .state_sort = __xfrm6_state_sort, +#endif }; void __init xfrm6_state_init(void) -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 18/23] [PATCH] [XFRM] IPV6: Update outbound state timestamp for each sending.
Mobile IPv6 enabled nodes will want to know traffic status of each binding (e.g. judgement to request binding refresh by correspondent node, or to keep home/care-of nonce alive by mobile node). The last used timestamp is an important hint about it. Based on MIPL2 kernel patch. --- net/ipv6/xfrm6_output.c |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 8792b5c..9ff4230 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -130,6 +130,11 @@ static int xfrm6_output_one(struct sk_bu x->curlft.bytes += skb->len; x->curlft.packets++; +#ifdef CONFIG_XFRM_ADVANCED + if (!xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY)) + x->curlft.use_time = (unsigned long) xtime.tv_sec; +#endif + spin_unlock_bh(&x->lock); skb->nh.raw = skb->data; -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 13/23] [PATCH] [XFRM]: Expand XFRM_MAX_DEPTH for routing header and destination options header.
XFRM_MAX_DEPTH is a limit of transformation states to be applied to the same flow. Two extension headers are used by Mobile IPv6 transformation. Based on MIPL2 kernel patch. --- include/net/xfrm.h |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index de62a8f..67fe834 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -327,7 +327,11 @@ struct xfrm_tmpl __u32 calgos; }; +#ifdef CONFIG_XFRM_ADVANCED +#define XFRM_MAX_DEPTH 6 +#else #define XFRM_MAX_DEPTH 4 +#endif struct xfrm_policy { -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/23] [PATCH] [XFRM] STATE: Common receive function for route optimization extension headers.
XFRM_STATE_WILDRECV flag is introduced; the last resort state is set it and receives packet which is not route optimized but uses such extension headers i.e. Mobile IPv6 signaling (binding update and acknowledgement). A node enabled Mobile IPv6 adds the state. Based on MIPL2 kernel patch. --- include/linux/xfrm.h |1 include/net/xfrm.h | 10 net/ipv6/ipv6_syms.c |3 + net/ipv6/xfrm6_input.c | 112 net/xfrm/xfrm_state.c |3 + 5 files changed, 129 insertions(+), 0 deletions(-) diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 55d1ce4..47e39f6 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -256,6 +256,7 @@ struct xfrm_usersa_info { #define XFRM_STATE_NOECN 1 #define XFRM_STATE_DECAP_DSCP 2 #define XFRM_STATE_NOPMTUDISC 4 +#define XFRM_STATE_WILDRECV8 }; struct xfrm_usersa_id { diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 8dcf6cd..f551bc6 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -964,6 +964,16 @@ extern int xfrm4_tunnel_register(struct extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); extern int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi); extern int xfrm6_rcv(struct sk_buff **pskb); +#ifdef CONFIG_XFRM_ADVANCED +extern int __xfrm6_rcv_one(struct sk_buff *skb, xfrm_address_t *daddr, + xfrm_address_t *saddr, u8 proto); +#else +static inline int __xfrm6_rcv_one(struct sk_buff *skb, xfrm_address_t *daddr, + xfrm_address_t *saddr, u8 proto) +{ + return -ENOSYS; +} +#endif extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c index 1648278..e8b8a5e 100644 --- a/net/ipv6/ipv6_syms.c +++ b/net/ipv6/ipv6_syms.c @@ -32,6 +32,9 @@ EXPORT_SYMBOL(ipv6_chk_addr); EXPORT_SYMBOL(in6_dev_finish_destroy); #ifdef CONFIG_XFRM EXPORT_SYMBOL(xfrm6_rcv); +#ifdef CONFIG_XFRM_ADVANCED +EXPORT_SYMBOL(__xfrm6_rcv_one); +#endif #endif EXPORT_SYMBOL(rt6_lookup); EXPORT_SYMBOL(ipv6_push_nfrag_opts); diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index 915e867..9dc8373 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c @@ -161,3 +161,115 @@ int xfrm6_rcv(struct sk_buff **pskb) { return xfrm6_rcv_spi(*pskb, 0); } + +#ifdef CONFIG_XFRM_ADVANCED +int __xfrm6_rcv_one(struct sk_buff *skb, xfrm_address_t *daddr, + xfrm_address_t *saddr, u8 proto) +{ + struct xfrm_state *x = NULL; + int wildcard = 0; + struct in6_addr any; + xfrm_address_t *xany; + struct xfrm_state *xfrm_vec_one = NULL; + int nh = 0; + int i = 0; + + ipv6_addr_set(&any, 0, 0, 0, 0); + xany = (xfrm_address_t *)&any; + + for (i = 0; i < 3; i++) { + xfrm_address_t *dst, *src; + switch (i) { + case 0: + dst = daddr; + src = saddr; + break; + case 1: + /* lookup state with wild-card source address */ + wildcard = 1; + dst = daddr; + src = xany; + break; + case 2: + default: + /* lookup state with wild-card addresses */ + wildcard = 1; /* XXX */ + dst = xany; + src = xany; + break; + } + + x = xfrm_state_lookup_byaddr(dst, src, proto, AF_INET6); + if (!x) + continue; + + spin_lock(&x->lock); + + if (wildcard) { + if ((x->props.flags & XFRM_STATE_WILDRECV) == 0) { + spin_unlock(&x->lock); + xfrm_state_put(x); + x = NULL; + continue; + } + } + + if (unlikely(x->km.state != XFRM_STATE_VALID)) { + spin_unlock(&x->lock); + xfrm_state_put(x); + x = NULL; + continue; + } + if (xfrm_state_check_expire(x)) { + spin_unlock(&x->lock); + xfrm_state_put(x); + x = NULL; + continue; + } + + nh = x->type->input(x, skb); + if (nh <= 0) { + spin_unlock(&x->lock); + xfrm_state_put(x); + x = NULL; + continue; + } + + x->curlft.bytes += skb->len; +
[PATCH 8/23] [PATCH] [XFRM] STATE: Add a hook to obtain local/remote outbound address.
Outbound transformation replaces both source and destination address with state's end-point addresses at the same time when IPsec tunnel mode. It is also required to change them for Mobile IPv6 route optimization, but we should care about the following differences: - changing result is not end-point but care-of address - either source or destination is replaced for each state This hook is a common platform to change outbound address. Based on MIPL2 kernel patch. --- include/net/xfrm.h |2 ++ net/ipv6/xfrm6_policy.c |8 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index bcda8c0..e14ae3c 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -271,6 +271,8 @@ struct xfrm_type int (*input)(struct xfrm_state *, struct sk_buff *skb); int (*output)(struct xfrm_state *, struct sk_buff *pskb); int (*place_find)(struct xfrm_state *, struct sk_buff *, u8 **); + xfrm_address_t *(*local_addr)(struct xfrm_state *, xfrm_address_t *); + xfrm_address_t *(*remote_addr)(struct xfrm_state *, xfrm_address_t *); /* Estimate maximal size of result of transformation of a dgram */ u32 (*get_max_size)(struct xfrm_state *, int size); }; diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 1d8489b..28bc272 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -118,8 +118,12 @@ __xfrm6_bundle_create(struct xfrm_policy dst1->next = dst_prev; dst_prev = dst1; if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { - remote = (struct in6_addr*)&xfrm[i]->id.daddr; - local = (struct in6_addr*)&xfrm[i]->props.saddr; + remote = (xfrm[i]->type->remote_addr) ? + (struct in6_addr*)xfrm[i]->type->remote_addr(xfrm[i], (xfrm_address_t *)remote): + (struct in6_addr*)&xfrm[i]->id.daddr; + local = (xfrm[i]->type->local_addr) ? + (struct in6_addr*)xfrm[i]->type->local_addr(xfrm[i], (xfrm_address_t *)local): + (struct in6_addr*)&xfrm[i]->props.saddr; tunnel = 1; } header_len += xfrm[i]->props.header_len; -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/23] [PATCH] [XFRM]: Restrict authentication algorithm only when inbound transformation protocol is IPsec.
For Mobile IPv6 usage, routing header or destination options header is used and it doesn't require this compare. It is checked only when IPsec template. Based on MIPL2 kernel patch. --- net/xfrm/xfrm_policy.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 1663ffa..e3c71b6 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -952,7 +952,8 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, st (x->id.spi == tmpl->id.spi || !tmpl->id.spi) && (x->props.reqid == tmpl->reqid || !tmpl->reqid) && x->props.mode == tmpl->mode && - (tmpl->aalgos & (1aalgos & (1 id.proto, IPSEC_PROTO_ANY))) && !(x->props.mode != XFRM_MODE_TRANSPORT && xfrm_state_addr_cmp(tmpl, x, family)); } -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 20/23] [PATCH] [XFRM] POLICY: sub policy support.
Sub policy is introduced. Main and sub policy are applied the same flow. (Policy that current kernel uses is named as main.) It is required another transformation policy management to keep IPsec and Mobile IPv6 lives separate. Policy which lives shorter time in kernel should be a sub i.e. normally main is for IPsec and sub is for Mobile IPv6. (Such usage as two IPsec policies on different database can be used, too.) Limitation or TODOs: - Sub policy is not supported for per socket one (it is always inserted as main). - Current kernel makes cached outbound with flowi to skip searching database. However this patch makes it disabled only when "two policies are used and the first matched one is bypass case" because neither flowi nor bundle information knows about transformation template size. --- include/linux/xfrm.h |7 + include/net/xfrm.h | 45 +++- net/xfrm/xfrm_policy.c | 255 +--- 3 files changed, 263 insertions(+), 44 deletions(-) diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 84a3e76..901bb65 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -104,6 +104,13 @@ struct xfrm_stats { enum { + XFRM_POLICY_TYPE_MAIN = 0, + XFRM_POLICY_TYPE_SUB= 1, + XFRM_POLICY_TYPE_MAX= 2 +}; + +enum +{ XFRM_POLICY_IN = 0, XFRM_POLICY_OUT = 1, XFRM_POLICY_FWD = 2, diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 05d4257..3fe621f 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -343,6 +343,7 @@ struct xfrm_policy atomic_trefcnt; struct timer_list timer; + u8 type; u32 priority; u32 index; struct xfrm_selectorselector; @@ -393,6 +394,19 @@ extern int xfrm_unregister_km(struct xfr extern struct xfrm_policy *xfrm_policy_list[XFRM_POLICY_MAX*2]; +#ifdef CONFIG_XFRM_SUB_POLICY +extern struct xfrm_policy *xfrm_policy_list_sub[XFRM_POLICY_MAX*2]; + +static inline int xfrm_policy_lists_empty(int dir) +{ + return (!xfrm_policy_list[dir] && !xfrm_policy_list_sub[dir]); +} +#else +static inline int xfrm_policy_lists_empty(int dir) +{ + return (!xfrm_policy_list[dir]); +} +#endif static inline void xfrm_pol_hold(struct xfrm_policy *policy) { @@ -408,6 +422,20 @@ static inline void xfrm_pol_put(struct x __xfrm_policy_destroy(policy); } +#ifdef CONFIG_XFRM_SUB_POLICY +static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols) +{ + int i; + for (i = npols - 1; i >= 0; --i) + xfrm_pol_put(pols[i]); +} +#else +static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols) +{ + xfrm_pol_put(pols[0]); +} +#endif + #define XFRM_DST_HSIZE 1024 static __inline__ @@ -738,8 +766,8 @@ static inline int xfrm_policy_check(stru { if (sk && sk->sk_policy[XFRM_POLICY_IN]) return __xfrm_policy_check(sk, dir, skb, family); - - return (!xfrm_policy_list[dir] && !skb->sp) || + + return (xfrm_policy_lists_empty(dir) && !skb->sp) || (skb->dst->flags & DST_NOPOLICY) || __xfrm_policy_check(sk, dir, skb, family); } @@ -759,7 +787,7 @@ extern int __xfrm_route_forward(struct s static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) { - return !xfrm_policy_list[XFRM_POLICY_OUT] || + return xfrm_policy_lists_empty(XFRM_POLICY_OUT) || (skb->dst->flags & DST_NOXFRM) || __xfrm_route_forward(skb, family); } @@ -1023,18 +1051,19 @@ static inline int xfrm_dst_lookup(struct #endif struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp); -extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *); +extern int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), void *); int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl); -struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel, +struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, + struct xfrm_selector *sel, struct xfrm_sec_ctx *ctx, int delete); -struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete); -void xfrm_policy_flush(void); +struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete); +void xfrm_policy_flush(u8 type); u32 xfrm_get_acqseq(void); void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create, unsigned short family); -extern void xfrm_policy_flush(void); +extern void xfrm_policy_flush(u8 type); extern int xfrm_sk_policy_insert(stru
[PATCH 21/23] [PATCH] [XFRM]: Add sorting interface for state and template.
Under two transformation policies it is required to merge them. This is a platform to sort state for outbound and templates for inbound respectively. Mobile IPv6 will use it. --- include/net/xfrm.h | 22 ++ net/xfrm/xfrm_policy.c | 16 ++-- net/xfrm/xfrm_state.c | 38 ++ 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 3fe621f..c1cc2f5 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -258,6 +258,10 @@ #endif struct xfrm_state *(*find_acq)(u8 mode, u32 reqid, u8 proto, xfrm_address_t *daddr, xfrm_address_t *saddr, int create); +#ifdef CONFIG_XFRM_SUB_POLICY + int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); + int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); +#endif }; extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); @@ -996,6 +1000,24 @@ static inline struct xfrm_state *xfrm_st return NULL; } #endif +#ifdef CONFIG_XFRM_SUB_POLICY +extern int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, + int n, unsigned short family); +extern int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, + int n, unsigned short family); +#else +static inline int xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, +int n, unsigned short family) +{ + return 0; +} + +static inline int xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, + int n, unsigned short family) +{ + return 0; +} +#endif extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); extern int xfrm_state_delete(struct xfrm_state *x); extern void xfrm_state_flush(u8 proto); diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index d105e2e..3e7b5a6 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -787,6 +787,8 @@ xfrm_tmpl_resolve(struct xfrm_policy **p struct xfrm_state **xfrm, unsigned short family) { + struct xfrm_state *tp[XFRM_MAX_DEPTH]; + struct xfrm_state **tpp = (npols > 1) ? tp : xfrm; int cnx = 0; int error; int ret; @@ -797,7 +799,8 @@ xfrm_tmpl_resolve(struct xfrm_policy **p error = -ENOBUFS; goto fail; } - ret = xfrm_tmpl_resolve_one(pols[i], fl, &xfrm[cnx], family); + + ret = xfrm_tmpl_resolve_one(pols[i], fl, &tpp[cnx], family); if (ret < 0) { error = ret; goto fail; @@ -805,11 +808,15 @@ xfrm_tmpl_resolve(struct xfrm_policy **p cnx += ret; } + /* found states are sorted for outbound processing */ + if (npols > 1) + xfrm_state_sort(xfrm, tpp, cnx, family); + return cnx; fail: for (cnx--; cnx>=0; cnx--) - xfrm_state_put(xfrm[cnx]); + xfrm_state_put(tpp[cnx]); return error; } @@ -1219,6 +1226,7 @@ #endif struct sec_path *sp; static struct sec_path dummy; struct xfrm_tmpl *tp[XFRM_MAX_DEPTH]; + struct xfrm_tmpl *stp[XFRM_MAX_DEPTH]; struct xfrm_tmpl **tpp = tp; int ti = 0; int i, k; @@ -1236,6 +1244,10 @@ #endif tpp[ti++] = &pols[pi]->xfrm_vec[i]; } xfrm_nr = ti; + if (npols > 1) { + xfrm_tmpl_sort(stp, tpp, xfrm_nr, family); + tpp = stp; + } /* For each tunnel xfrm, find the first matching tmpl. * For each tmpl before that, find corresponding xfrm. diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 0c74e7c..8ef9831 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -750,6 +750,44 @@ xfrm_find_acq(u8 mode, u32 reqid, u8 pro } EXPORT_SYMBOL(xfrm_find_acq); +#ifdef CONFIG_XFRM_SUB_POLICY +int +xfrm_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n, + unsigned short family) +{ + int err = 0; + struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); + if (!afinfo) + return -EAFNOSUPPORT; + + spin_lock_bh(&xfrm_state_lock); + if (afinfo->tmpl_sort) + err = afinfo->tmpl_sort(dst, src, n); + spin_unlock_bh(&xfrm_state_lock); + xfrm_state_put_afinfo(afinfo); + return err; +} +EXPORT_SYMBOL(xfrm_tmpl_sort); + +int +xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n, +
[PATCH 15/23] [PATCH] [XFRM] STATE: Allow non IPsec protocol.
It will be added two more transformation protocols (routing header and destination options header) by Mobile IPv6. xfrm_id_proto_match() can be handle zero as all, IPSEC_PROTO_ANY as all IPsec and otherwise as exact one. Based on MIPL2 kernel patch. --- include/net/xfrm.h |7 +++ net/xfrm/xfrm_user.c |4 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 67fe834..0b8edad 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -881,7 +881,14 @@ static inline int xfrm_state_kern(struct static inline int xfrm_id_proto_match(u8 proto, u8 userproto) { +#ifdef CONFIG_XFRM_ADVANCED + return (!userproto || proto == userproto || + (userproto == IPSEC_PROTO_ANY && (proto == IPPROTO_AH || + proto == IPPROTO_ESP || + proto == IPPROTO_COMP))); +#else return (userproto == IPSEC_PROTO_ANY || proto == userproto); +#endif } /* diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 13fe172..a91367d 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -598,7 +598,11 @@ static int xfrm_dump_sa(struct sk_buff * info.nlmsg_flags = NLM_F_MULTI; info.this_idx = 0; info.start_idx = cb->args[0]; +#ifdef CONFIG_XFRM_ADVANCED + (void) xfrm_state_walk(0, dump_one_state, &info); +#else (void) xfrm_state_walk(IPSEC_PROTO_ANY, dump_one_state, &info); +#endif cb->args[0] = info.this_idx; return skb->len; -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/23] [PATCH] [XFRM]: Fix message about transformation user interface.
Transformation user interface is not only for IPsec. Based on MIPL2 kernel patch. --- net/xfrm/Kconfig |6 +++--- net/xfrm/xfrm_user.c |2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig index 95f4f09..50f2fb3 100644 --- a/net/xfrm/Kconfig +++ b/net/xfrm/Kconfig @@ -6,11 +6,11 @@ config XFRM depends on NET config XFRM_USER - tristate "IPsec user configuration interface" + tristate "Transformation user configuration interface" depends on INET && XFRM ---help--- - Support for IPsec user configuration interface used - by native Linux tools. + Support for Transformation(XFRM) user configuration interface + like IPsec used by native Linux tools. If unsure, say Y. diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 9516da3..f92d163 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -1949,7 +1949,7 @@ static int __init xfrm_user_init(void) { struct sock *nlsk; - printk(KERN_INFO "Initializing IPsec netlink socket\n"); + printk(KERN_INFO "Initializing XFRM netlink socket\n"); nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX, xfrm_netlink_rcv, THIS_MODULE); -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/23] [PATCH] [XFRM]: Add XFRM_MODE_xxx for future use.
Transformation mode is used as either IPsec transport or tunnel. It is required to add two more items, route-optimization and inbound trigger by Mobile IPv6. Based on MIPL2 kernel patch. --- include/linux/xfrm.h|9 - include/net/xfrm.h |2 +- net/ipv4/ah4.c |2 +- net/ipv4/esp4.c |6 +++--- net/ipv4/ipcomp.c |8 net/ipv4/xfrm4_input.c |2 +- net/ipv4/xfrm4_output.c |6 +++--- net/ipv4/xfrm4_policy.c |2 +- net/ipv4/xfrm4_state.c |2 +- net/ipv4/xfrm4_tunnel.c |2 +- net/ipv6/ah6.c |2 +- net/ipv6/esp6.c |4 ++-- net/ipv6/ipcomp6.c |6 +++--- net/ipv6/xfrm6_input.c |2 +- net/ipv6/xfrm6_output.c |6 +++--- net/ipv6/xfrm6_policy.c |2 +- net/ipv6/xfrm6_state.c |2 +- net/ipv6/xfrm6_tunnel.c |2 +- net/key/af_key.c|6 +++--- net/xfrm/xfrm_policy.c | 11 ++- net/xfrm/xfrm_user.c|4 ++-- 21 files changed, 48 insertions(+), 40 deletions(-) diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 6b42cc4..7dff1c8 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -178,6 +178,13 @@ struct xfrm_user_sec_ctx { __u16 ctx_len; }; +enum { + XFRM_MODE_TRANSPORT = 0, + XFRM_MODE_TUNNEL = 1, + XFRM_MODE_ROUTEOPTIMIZATION = 2, + XFRM_MODE_IN_TRIGGER = 3, +}; + struct xfrm_user_tmpl { struct xfrm_id id; __u16 family; @@ -243,7 +250,7 @@ struct xfrm_usersa_info { __u32 seq; __u32 reqid; __u16 family; - __u8mode; /* 0=transport,1=tunnel */ + __u8mode; /* XFRM_MODE_xxx */ __u8replay_window; __u8flags; #define XFRM_STATE_NOECN 1 diff --git a/include/net/xfrm.h b/include/net/xfrm.h index afa508d..ddb153d 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -289,7 +289,7 @@ struct xfrm_tmpl __u32 reqid; -/* Mode: transport/tunnel */ +/* Mode: transport, tunnel etc. */ __u8mode; /* Sharing mode: unique, this session only, this user only etc. */ diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index e2e4771..fa16bc2 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -257,7 +257,7 @@ static int ah_init_state(struct xfrm_sta goto error; x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len); - if (x->props.mode) + if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct iphdr); x->data = ahp; diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 9d1881c..dd4edd1 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -240,7 +240,7 @@ static int esp_input(struct xfrm_state * *as per draft-ietf-ipsec-udp-encaps-06, *section 3.1.2 */ - if (!x->props.mode) + if (x->props.mode == XFRM_MODE_TRANSPORT) skb->ip_summed = CHECKSUM_UNNECESSARY; } @@ -263,7 +263,7 @@ static u32 esp4_get_max_size(struct xfrm struct esp_data *esp = x->data; u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); - if (x->props.mode) { + if (x->props.mode == XFRM_MODE_TUNNEL) { mtu = ALIGN(mtu + 2, blksize); } else { /* The worst case. */ @@ -377,7 +377,7 @@ static int esp_init_state(struct xfrm_st if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len)) goto error; x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; - if (x->props.mode) + if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct iphdr); if (x->encap) { struct xfrm_encap_tmpl *encap = x->encap; diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 95278b2..a4c35f7 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -194,7 +194,7 @@ static int ipcomp_output(struct xfrm_sta return 0; out_ok: - if (x->props.mode) + if (x->props.mode == XFRM_MODE_TUNNEL) ip_send_check(iph); return 0; } @@ -234,7 +234,7 @@ static struct xfrm_state *ipcomp_tunnel_ t->id.daddr.a4 = x->id.daddr.a4; memcpy(&t->sel, &x->sel, sizeof(t->sel)); t->props.family = AF_INET; - t->props.mode = 1; + t->props.mode = XFRM_MODE_TUNNEL; t->props.saddr.a4 = x->props.saddr.a4; t->props.flags = x->props.flags; @@ -434,7 +434,7 @@ static int ipcomp_init_state(struct xfrm memset(ipcd, 0, sizeof(*ipcd)); x->props.header_len = 0; - if (x->props.mode) + if
[PATCH 3/23] [PATCH] [XFRM]: Add Kconfig to enable advanced transformation.
This option is for enhanced transformation features and it will be used by Mobile IPv6. Based on MIPL2 kernel patch. --- net/xfrm/Kconfig |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig index 0c1c043..95f4f09 100644 --- a/net/xfrm/Kconfig +++ b/net/xfrm/Kconfig @@ -14,6 +14,14 @@ config XFRM_USER If unsure, say Y. +config XFRM_ADVANCED + bool "Transformation advanced functions (EXPERIMENTAL)" + depends on XFRM && EXPERIMENTAL + ---help--- + Support advanced transformation for developers. + + If unsure, say N. + config NET_KEY tristate "PF_KEY sockets" select XFRM -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/23] [PATCH] [XFRM] STATE: Add source address list.
Support source address based searching. Mobile IPv6 will use it. Based on MIPL2 kernel patch. --- include/linux/xfrm.h |1 + include/net/xfrm.h | 32 net/ipv4/xfrm4_state.c |5 + net/ipv6/xfrm6_state.c |5 + net/xfrm/xfrm_state.c | 38 ++ 5 files changed, 81 insertions(+), 0 deletions(-) diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 7dff1c8..55d1ce4 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -263,6 +263,7 @@ struct xfrm_usersa_id { __u32 spi; __u16 family; __u8proto; + xfrm_address_t saddr; }; struct xfrm_aevent_id { diff --git a/include/net/xfrm.h b/include/net/xfrm.h index ca537b5..75649da 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -94,6 +94,9 @@ struct xfrm_state { /* Note: bydst is re-used during gc */ struct list_headbydst; +#ifdef CONFIG_XFRM_ADVANCED + struct list_headbysrc; +#endif struct list_headbyspi; atomic_trefcnt; @@ -235,6 +238,9 @@ struct xfrm_state_afinfo { unsigned short family; rwlock_tlock; struct list_head*state_bydst; +#ifdef CONFIG_XFRM_ADVANCED + struct list_head*state_bysrc; +#endif struct list_head*state_byspi; int (*init_flags)(struct xfrm_state *x); void(*init_tempsel)(struct xfrm_state *x, struct flowi *fl, @@ -411,6 +417,32 @@ unsigned xfrm_dst_hash(xfrm_address_t *a return 0; } +#ifdef CONFIG_XFRM_ADVANCED +static __inline__ +unsigned __xfrm4_src_hash(xfrm_address_t *addr) +{ + return __xfrm4_dst_hash(addr); +} + +static __inline__ +unsigned __xfrm6_src_hash(xfrm_address_t *addr) +{ + return __xfrm6_dst_hash(addr); +} + +static __inline__ +unsigned xfrm_src_hash(xfrm_address_t *addr, unsigned short family) +{ + switch (family) { + case AF_INET: + return __xfrm4_src_hash(addr); + case AF_INET6: + return __xfrm6_src_hash(addr); + } + return 0; +} +#endif + static __inline__ unsigned __xfrm4_spi_hash(xfrm_address_t *addr, u32 spi, u8 proto) { diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 171cdc5..6de2ce0 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c @@ -122,6 +122,11 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 add_timer(&x0->timer); xfrm_state_hold(x0); list_add_tail(&x0->bydst, xfrm4_state_afinfo.state_bydst+h); +#ifdef CONFIG_XFRM_ADVANCED + h = __xfrm4_src_hash(saddr); + xfrm_state_hold(x0); + list_add_tail(&x0->bysrc, xfrm4_state_afinfo.state_bysrc+h); +#endif wake_up(&km_waitq); } if (x0) diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 71c40bb..00b6c17 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c @@ -126,6 +126,11 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8 add_timer(&x0->timer); xfrm_state_hold(x0); list_add_tail(&x0->bydst, xfrm6_state_afinfo.state_bydst+h); +#ifdef CONFIG_XFRM_ADVANCED + h = __xfrm6_src_hash(saddr); + xfrm_state_hold(x0); + list_add_tail(&x0->bysrc, xfrm6_state_afinfo.state_bysrc+h); +#endif wake_up(&km_waitq); } if (x0) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 6cf080f..1942bb1 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -45,6 +45,9 @@ static DEFINE_SPINLOCK(xfrm_state_lock); * Also, it can be used by ah/esp icmp error handler to find offending SA. */ static struct list_head xfrm_state_bydst[XFRM_DST_HSIZE]; +#ifdef CONFIG_XFRM_ADVANCED +static struct list_head xfrm_state_bysrc[XFRM_DST_HSIZE]; +#endif static struct list_head xfrm_state_byspi[XFRM_DST_HSIZE]; DECLARE_WAIT_QUEUE_HEAD(km_waitq); @@ -199,6 +202,9 @@ struct xfrm_state *xfrm_state_alloc(void atomic_set(&x->refcnt, 1); atomic_set(&x->tunnel_users, 0); INIT_LIST_HEAD(&x->bydst); +#ifdef CONFIG_XFRM_ADVANCED + INIT_LIST_HEAD(&x->bysrc); +#endif INIT_LIST_HEAD(&x->byspi); init_timer(&x->timer); x->timer.function = xfrm_timer_handler; @@ -239,6 +245,10 @@ int __xfrm_state_delete(struct xfrm_stat spin_lock(&xfrm_state_lock); list_del(&x->bydst); __xfrm_state_put(x); +#ifdef CONFIG_XFRM_ADVANCED + list_del(&x->bysrc); + __xfrm_state_put(x); +#endif if (x->id.spi) { list_del(&x->byspi); __xfrm_state
[PATCH 2/23] [PATCH] [XFRM]: Introduce a helper to compare id protocol.
Put the helper to header for future use. --- include/net/xfrm.h|6 ++ net/xfrm/xfrm_state.c |6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index ddb153d..ca537b5 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -10,6 +10,7 @@ #include #include #include #include +#include #include #include @@ -826,6 +827,11 @@ static inline int xfrm_state_kern(struct return atomic_read(&x->tunnel_users); } +static inline int xfrm_id_proto_match(u8 proto, u8 userproto) +{ + return (userproto == IPSEC_PROTO_ANY || proto == userproto); +} + /* * xfrm algorithm information */ diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 93a2f36..6cf080f 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -293,7 +293,7 @@ void xfrm_state_flush(u8 proto) restart: list_for_each_entry(x, xfrm_state_bydst+i, bydst) { if (!xfrm_state_kern(x) && - (proto == IPSEC_PROTO_ANY || x->id.proto == proto)) { + xfrm_id_proto_match(x->id.proto, proto)) { xfrm_state_hold(x); spin_unlock_bh(&xfrm_state_lock); @@ -763,7 +763,7 @@ int xfrm_state_walk(u8 proto, int (*func spin_lock_bh(&xfrm_state_lock); for (i = 0; i < XFRM_DST_HSIZE; i++) { list_for_each_entry(x, xfrm_state_bydst+i, bydst) { - if (proto == IPSEC_PROTO_ANY || x->id.proto == proto) + if (xfrm_id_proto_match(x->id.proto, proto)) count++; } } @@ -774,7 +774,7 @@ int xfrm_state_walk(u8 proto, int (*func for (i = 0; i < XFRM_DST_HSIZE; i++) { list_for_each_entry(x, xfrm_state_bydst+i, bydst) { - if (proto != IPSEC_PROTO_ANY && x->id.proto != proto) + if (!xfrm_id_proto_match(x->id.proto, proto)) continue; err = func(x, --count, data); if (err) -- 1.4.1 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/23][XFRM] MIPv6 CN introduction (part A) (Re: [RFC] Mobile IPv6 introduction)
Please see patches about "Avanced XFRM for CN", following this mail. These are just for review, and it is against 2.6.17. "Avanced XFRM for CN" tree is consists of: A. XFRM extension for route optimization B. IPv6 extension headers: new type (2) of routing header new TLV option for destination options header: home address option new header for signaling: mobility header Part B patches depend on A. Let me start part A first. Part A is also available as mip6cn-20060716-review branch at: git://git.skbuff.net:9419/gitroot/nakam/linux-2.6-mip6cn-xfrm > 3. Advanced XFRM for CN > "Route optimization" defined MIPv6 specification > is designed as XFRM extension. IPv6 extension headers > handling is included, too. > This feature is required by all MIPv6 nodes(CN, MN, HA) then it can > be said MIPv6 platform. -- Masahide NAKAMURA - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC] Mobile IPv6 introduction
Hello, Let me introduce Mobile IPv6(RFC3775) patch and its outline. We USAGI project and HUT Go/Core project have developed for Mobile IPv6(MIPv6) stack on 2.6 tree as MIPL2 for several years. Our aim is to make kernel patch smaller (than MIPL1 which is for 2.4 kernel). We find out we have 4 categories for the patch: 1. IPv6 policy routing 2. IPsec MIGRATE 3. Advanced XFRM for Correspondent Node(CN) 4. MISC 3, 4 are MIPv6 specific feature but 1, 2 are not. It can be discussed in parallel about 1, 2, 3 because they don't depend on others. 1. IPv6 policy routing Thomas and Yoshifuji have already started to discuss and work for it. This is required by Mobile Node(MN) and used by Home Agent(HA). 2. IPsec MIGRATE This is an interface to update IPsec end-point address of SAD/SPD. (there is an IETF draft: draft-sugimoto-mip6-pfkey-migrate-XX) This is required by MN and HA to use IPsec tunnel. 3. Advanced XFRM for CN "Route optimization" defined MIPv6 specification is designed as XFRM extension. IPv6 extension headers handling is included, too. This feature is required by all MIPv6 nodes(CN, MN, HA) then it can be said MIPv6 platform. 4. MISC This is a set of small patches but works with the above categories since they are finally confirmed as the MIPv6 node behavior; e.g. home addressing for MN, proxy forwarding for HA. At first I'll send patches about category "3" very soon, just for review. Can you check them? Thanks, -- Masahide NAKAMURA - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] include/linux/netfilter_bridge.h: header cleanup
On Sat, Jul 29, 2006 at 12:55:28AM -0700, Andrew Morton wrote: > On Sat, 29 Jul 2006 11:45:45 +0400 > Alexey Dobriyan <[EMAIL PROTECTED]> wrote: > > > Header doesn't use anything from atomic.h. > > > OK, but.. > > > It fixes headers_check warning: > > > > include/linux/netfilter_bridge.h requires asm/atomic.h, which does not exist > > asm/atomic.h _does_ exist. What's up with that? In tree, yes. In exported headers, no. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] include/linux/netfilter_bridge.h: header cleanup
On Sat, 29 Jul 2006 11:45:45 +0400 Alexey Dobriyan <[EMAIL PROTECTED]> wrote: > Header doesn't use anything from atomic.h. OK, but.. > It fixes headers_check warning: > > include/linux/netfilter_bridge.h requires asm/atomic.h, which does not exist asm/atomic.h _does_ exist. What's up with that? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] include/linux/netfilter_bridge.h: header cleanup
Header doesn't use anything from atomic.h. It fixes headers_check warning: include/linux/netfilter_bridge.h requires asm/atomic.h, which does not exist Compile tested on alpha arm i386-up sparcsparc64-up x86_64 alpha-up i386 sparc64 sparc-upx86_64-up Signed-off-by: Alexey Dobriyan <[EMAIL PROTECTED]> --- include/linux/netfilter_bridge.h |1 - 1 file changed, 1 deletion(-) --- a/include/linux/netfilter_bridge.h +++ b/include/linux/netfilter_bridge.h @@ -6,7 +6,6 @@ #define __LINUX_BRIDGE_NETFILTER_H #include #if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER) -#include #include #endif - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RESEND 3/5] [NET]: Protocol Independant Policy Routing Rules Framework
On Sat, 2006-07-29 at 03:40 +0200, Patrick McHardy wrote: > Martin Josefsson wrote: > > As a somewhat related note, I've just digged a bit through RCU land, > > talked to dipankar and mckenney, and discovered that rcu_read_lock() / > > rcu_read_unlock() aren't strictly needed in softirqs since preempt is > > already disabled in softirqs. This means that you can use the result of > > the rcu read-side critical outside of the rcu_read_lock() / > > Thats true, but in this case the code is executed both in softirq- > and user-context. Using rcu_read_lock and still relying on softirq > properties outside the locked section is also very confusing in my > opinion. Yes it is very fishy relying on the softirq properties, especially since they don't apply to -rt kernels and that there might be other changes in this area in the future. It's not recommended. -- /Martin signature.asc Description: This is a digitally signed message part