diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/802/p8023.c | 2 | ||||
| -rw-r--r-- | net/atm/signaling.c | 3 | ||||
| -rw-r--r-- | net/bluetooth/hci_sock.c | 10 | ||||
| -rw-r--r-- | net/bluetooth/rfcomm/core.c | 13 | ||||
| -rw-r--r-- | net/bridge/br_netfilter.c | 4 | ||||
| -rw-r--r-- | net/bridge/br_stp_if.c | 4 | ||||
| -rw-r--r-- | net/core/datagram.c | 81 | ||||
| -rw-r--r-- | net/ipv4/icmp.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ip_gre.c | 3 | ||||
| -rw-r--r-- | net/ipv4/ip_output.c | 16 | ||||
| -rw-r--r-- | net/ipv4/ipip.c | 3 | ||||
| -rw-r--r-- | net/ipv4/netfilter.c | 41 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_nat_standalone.c | 6 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 5 | ||||
| -rw-r--r-- | net/ipv4/xfrm4_output.c | 13 | ||||
| -rw-r--r-- | net/ipv6/icmp.c | 6 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 2 | ||||
| -rw-r--r-- | net/ipv6/raw.c | 5 | ||||
| -rw-r--r-- | net/netfilter/Kconfig | 10 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_core.c | 5 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_proto_tcp.c | 4 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_proto_udp.c | 4 | ||||
| -rw-r--r-- | net/netlink/genetlink.c | 11 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 4 |
24 files changed, 179 insertions, 78 deletions
diff --git a/net/802/p8023.c b/net/802/p8023.c index d23e906456eb..53cf05709283 100644 --- a/net/802/p8023.c +++ b/net/802/p8023.c | |||
| @@ -59,3 +59,5 @@ void destroy_8023_client(struct datalink_proto *dl) | |||
| 59 | 59 | ||
| 60 | EXPORT_SYMBOL(destroy_8023_client); | 60 | EXPORT_SYMBOL(destroy_8023_client); |
| 61 | EXPORT_SYMBOL(make_8023_client); | 61 | EXPORT_SYMBOL(make_8023_client); |
| 62 | |||
| 63 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/atm/signaling.c b/net/atm/signaling.c index e7211a7f382c..93ad59a28ef5 100644 --- a/net/atm/signaling.c +++ b/net/atm/signaling.c | |||
| @@ -56,7 +56,8 @@ static void sigd_put_skb(struct sk_buff *skb) | |||
| 56 | remove_wait_queue(&sigd_sleep,&wait); | 56 | remove_wait_queue(&sigd_sleep,&wait); |
| 57 | #else | 57 | #else |
| 58 | if (!sigd) { | 58 | if (!sigd) { |
| 59 | printk(KERN_WARNING "atmsvc: no signaling demon\n"); | 59 | if (net_ratelimit()) |
| 60 | printk(KERN_WARNING "atmsvc: no signaling demon\n"); | ||
| 60 | kfree_skb(skb); | 61 | kfree_skb(skb); |
| 61 | return; | 62 | return; |
| 62 | } | 63 | } |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index bdb6458c6bd5..97bdec73d17e 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
| @@ -143,13 +143,15 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) | |||
| 143 | static int hci_sock_release(struct socket *sock) | 143 | static int hci_sock_release(struct socket *sock) |
| 144 | { | 144 | { |
| 145 | struct sock *sk = sock->sk; | 145 | struct sock *sk = sock->sk; |
| 146 | struct hci_dev *hdev = hci_pi(sk)->hdev; | 146 | struct hci_dev *hdev; |
| 147 | 147 | ||
| 148 | BT_DBG("sock %p sk %p", sock, sk); | 148 | BT_DBG("sock %p sk %p", sock, sk); |
| 149 | 149 | ||
| 150 | if (!sk) | 150 | if (!sk) |
| 151 | return 0; | 151 | return 0; |
| 152 | 152 | ||
| 153 | hdev = hci_pi(sk)->hdev; | ||
| 154 | |||
| 153 | bt_sock_unlink(&hci_sk_list, sk); | 155 | bt_sock_unlink(&hci_sk_list, sk); |
| 154 | 156 | ||
| 155 | if (hdev) { | 157 | if (hdev) { |
| @@ -311,14 +313,18 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *add | |||
| 311 | { | 313 | { |
| 312 | struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr; | 314 | struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr; |
| 313 | struct sock *sk = sock->sk; | 315 | struct sock *sk = sock->sk; |
| 316 | struct hci_dev *hdev = hci_pi(sk)->hdev; | ||
| 314 | 317 | ||
| 315 | BT_DBG("sock %p sk %p", sock, sk); | 318 | BT_DBG("sock %p sk %p", sock, sk); |
| 316 | 319 | ||
| 320 | if (!hdev) | ||
| 321 | return -EBADFD; | ||
| 322 | |||
| 317 | lock_sock(sk); | 323 | lock_sock(sk); |
| 318 | 324 | ||
| 319 | *addr_len = sizeof(*haddr); | 325 | *addr_len = sizeof(*haddr); |
| 320 | haddr->hci_family = AF_BLUETOOTH; | 326 | haddr->hci_family = AF_BLUETOOTH; |
| 321 | haddr->hci_dev = hci_pi(sk)->hdev->id; | 327 | haddr->hci_dev = hdev->id; |
| 322 | 328 | ||
| 323 | release_sock(sk); | 329 | release_sock(sk); |
| 324 | return 0; | 330 | return 0; |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 0d89d6434136..5b4253c61f62 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
| @@ -46,13 +46,15 @@ | |||
| 46 | #include <net/bluetooth/l2cap.h> | 46 | #include <net/bluetooth/l2cap.h> |
| 47 | #include <net/bluetooth/rfcomm.h> | 47 | #include <net/bluetooth/rfcomm.h> |
| 48 | 48 | ||
| 49 | #define VERSION "1.6" | ||
| 50 | |||
| 51 | #ifndef CONFIG_BT_RFCOMM_DEBUG | 49 | #ifndef CONFIG_BT_RFCOMM_DEBUG |
| 52 | #undef BT_DBG | 50 | #undef BT_DBG |
| 53 | #define BT_DBG(D...) | 51 | #define BT_DBG(D...) |
| 54 | #endif | 52 | #endif |
| 55 | 53 | ||
| 54 | #define VERSION "1.7" | ||
| 55 | |||
| 56 | static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU; | ||
| 57 | |||
| 56 | static struct task_struct *rfcomm_thread; | 58 | static struct task_struct *rfcomm_thread; |
| 57 | 59 | ||
| 58 | static DECLARE_MUTEX(rfcomm_sem); | 60 | static DECLARE_MUTEX(rfcomm_sem); |
| @@ -623,7 +625,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst | |||
| 623 | /* Set L2CAP options */ | 625 | /* Set L2CAP options */ |
| 624 | sk = sock->sk; | 626 | sk = sock->sk; |
| 625 | lock_sock(sk); | 627 | lock_sock(sk); |
| 626 | l2cap_pi(sk)->imtu = RFCOMM_MAX_L2CAP_MTU; | 628 | l2cap_pi(sk)->imtu = l2cap_mtu; |
| 627 | release_sock(sk); | 629 | release_sock(sk); |
| 628 | 630 | ||
| 629 | s = rfcomm_session_add(sock, BT_BOUND); | 631 | s = rfcomm_session_add(sock, BT_BOUND); |
| @@ -1868,7 +1870,7 @@ static int rfcomm_add_listener(bdaddr_t *ba) | |||
| 1868 | /* Set L2CAP options */ | 1870 | /* Set L2CAP options */ |
| 1869 | sk = sock->sk; | 1871 | sk = sock->sk; |
| 1870 | lock_sock(sk); | 1872 | lock_sock(sk); |
| 1871 | l2cap_pi(sk)->imtu = RFCOMM_MAX_L2CAP_MTU; | 1873 | l2cap_pi(sk)->imtu = l2cap_mtu; |
| 1872 | release_sock(sk); | 1874 | release_sock(sk); |
| 1873 | 1875 | ||
| 1874 | /* Start listening on the socket */ | 1876 | /* Start listening on the socket */ |
| @@ -2070,6 +2072,9 @@ static void __exit rfcomm_exit(void) | |||
| 2070 | module_init(rfcomm_init); | 2072 | module_init(rfcomm_init); |
| 2071 | module_exit(rfcomm_exit); | 2073 | module_exit(rfcomm_exit); |
| 2072 | 2074 | ||
| 2075 | module_param(l2cap_mtu, uint, 0644); | ||
| 2076 | MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection"); | ||
| 2077 | |||
| 2073 | MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>"); | 2078 | MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>"); |
| 2074 | MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION); | 2079 | MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION); |
| 2075 | MODULE_VERSION(VERSION); | 2080 | MODULE_VERSION(VERSION); |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index c06cb0983530..6bb0c7eb1ef0 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
| @@ -805,8 +805,8 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, | |||
| 805 | print_error: | 805 | print_error: |
| 806 | if (skb->dev != NULL) { | 806 | if (skb->dev != NULL) { |
| 807 | printk("[%s]", skb->dev->name); | 807 | printk("[%s]", skb->dev->name); |
| 808 | if (bridge_parent(skb->dev)) | 808 | if (realoutdev) |
| 809 | printk("[%s]", bridge_parent(skb->dev)->name); | 809 | printk("[%s]", realoutdev->name); |
| 810 | } | 810 | } |
| 811 | printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw, | 811 | printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw, |
| 812 | skb->data); | 812 | skb->data); |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index cc047f7fb6ef..35cf3a074087 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
| @@ -67,7 +67,7 @@ void br_stp_disable_bridge(struct net_bridge *br) | |||
| 67 | { | 67 | { |
| 68 | struct net_bridge_port *p; | 68 | struct net_bridge_port *p; |
| 69 | 69 | ||
| 70 | spin_lock(&br->lock); | 70 | spin_lock_bh(&br->lock); |
| 71 | list_for_each_entry(p, &br->port_list, list) { | 71 | list_for_each_entry(p, &br->port_list, list) { |
| 72 | if (p->state != BR_STATE_DISABLED) | 72 | if (p->state != BR_STATE_DISABLED) |
| 73 | br_stp_disable_port(p); | 73 | br_stp_disable_port(p); |
| @@ -76,7 +76,7 @@ void br_stp_disable_bridge(struct net_bridge *br) | |||
| 76 | 76 | ||
| 77 | br->topology_change = 0; | 77 | br->topology_change = 0; |
| 78 | br->topology_change_detected = 0; | 78 | br->topology_change_detected = 0; |
| 79 | spin_unlock(&br->lock); | 79 | spin_unlock_bh(&br->lock); |
| 80 | 80 | ||
| 81 | del_timer_sync(&br->hello_timer); | 81 | del_timer_sync(&br->hello_timer); |
| 82 | del_timer_sync(&br->topology_change_timer); | 82 | del_timer_sync(&br->topology_change_timer); |
diff --git a/net/core/datagram.c b/net/core/datagram.c index f8d322e1ea92..b8ce6bf81188 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
| @@ -247,49 +247,74 @@ EXPORT_SYMBOL(skb_kill_datagram); | |||
| 247 | int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, | 247 | int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, |
| 248 | struct iovec *to, int len) | 248 | struct iovec *to, int len) |
| 249 | { | 249 | { |
| 250 | int i, err, fraglen, end = 0; | 250 | int start = skb_headlen(skb); |
| 251 | struct sk_buff *next = skb_shinfo(skb)->frag_list; | 251 | int i, copy = start - offset; |
| 252 | 252 | ||
| 253 | if (!len) | 253 | /* Copy header. */ |
| 254 | return 0; | 254 | if (copy > 0) { |
| 255 | if (copy > len) | ||
| 256 | copy = len; | ||
| 257 | if (memcpy_toiovec(to, skb->data + offset, copy)) | ||
| 258 | goto fault; | ||
| 259 | if ((len -= copy) == 0) | ||
| 260 | return 0; | ||
| 261 | offset += copy; | ||
| 262 | } | ||
| 255 | 263 | ||
| 256 | next_skb: | 264 | /* Copy paged appendix. Hmm... why does this look so complicated? */ |
| 257 | fraglen = skb_headlen(skb); | 265 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
| 258 | i = -1; | 266 | int end; |
| 259 | 267 | ||
| 260 | while (1) { | 268 | BUG_TRAP(start <= offset + len); |
| 261 | int start = end; | ||
| 262 | 269 | ||
| 263 | if ((end += fraglen) > offset) { | 270 | end = start + skb_shinfo(skb)->frags[i].size; |
| 264 | int copy = end - offset, o = offset - start; | 271 | if ((copy = end - offset) > 0) { |
| 272 | int err; | ||
| 273 | u8 *vaddr; | ||
| 274 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | ||
| 275 | struct page *page = frag->page; | ||
| 265 | 276 | ||
| 266 | if (copy > len) | 277 | if (copy > len) |
| 267 | copy = len; | 278 | copy = len; |
| 268 | if (i == -1) | 279 | vaddr = kmap(page); |
| 269 | err = memcpy_toiovec(to, skb->data + o, copy); | 280 | err = memcpy_toiovec(to, vaddr + frag->page_offset + |
| 270 | else { | 281 | offset - start, copy); |
| 271 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 282 | kunmap(page); |
| 272 | struct page *page = frag->page; | ||
| 273 | void *p = kmap(page) + frag->page_offset + o; | ||
| 274 | err = memcpy_toiovec(to, p, copy); | ||
| 275 | kunmap(page); | ||
| 276 | } | ||
| 277 | if (err) | 283 | if (err) |
| 278 | goto fault; | 284 | goto fault; |
| 279 | if (!(len -= copy)) | 285 | if (!(len -= copy)) |
| 280 | return 0; | 286 | return 0; |
| 281 | offset += copy; | 287 | offset += copy; |
| 282 | } | 288 | } |
| 283 | if (++i >= skb_shinfo(skb)->nr_frags) | 289 | start = end; |
| 284 | break; | ||
| 285 | fraglen = skb_shinfo(skb)->frags[i].size; | ||
| 286 | } | 290 | } |
| 287 | if (next) { | 291 | |
| 288 | skb = next; | 292 | if (skb_shinfo(skb)->frag_list) { |
| 289 | BUG_ON(skb_shinfo(skb)->frag_list); | 293 | struct sk_buff *list = skb_shinfo(skb)->frag_list; |
| 290 | next = skb->next; | 294 | |
| 291 | goto next_skb; | 295 | for (; list; list = list->next) { |
| 296 | int end; | ||
| 297 | |||
| 298 | BUG_TRAP(start <= offset + len); | ||
| 299 | |||
| 300 | end = start + list->len; | ||
| 301 | if ((copy = end - offset) > 0) { | ||
| 302 | if (copy > len) | ||
| 303 | copy = len; | ||
| 304 | if (skb_copy_datagram_iovec(list, | ||
| 305 | offset - start, | ||
| 306 | to, copy)) | ||
| 307 | goto fault; | ||
| 308 | if ((len -= copy) == 0) | ||
| 309 | return 0; | ||
| 310 | offset += copy; | ||
| 311 | } | ||
| 312 | start = end; | ||
| 313 | } | ||
| 292 | } | 314 | } |
| 315 | if (!len) | ||
| 316 | return 0; | ||
| 317 | |||
| 293 | fault: | 318 | fault: |
| 294 | return -EFAULT; | 319 | return -EFAULT; |
| 295 | } | 320 | } |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 4d1c40972a4b..e7bbff4340bb 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -192,7 +192,7 @@ int sysctl_icmp_echo_ignore_all; | |||
| 192 | int sysctl_icmp_echo_ignore_broadcasts = 1; | 192 | int sysctl_icmp_echo_ignore_broadcasts = 1; |
| 193 | 193 | ||
| 194 | /* Control parameter - ignore bogus broadcast responses? */ | 194 | /* Control parameter - ignore bogus broadcast responses? */ |
| 195 | int sysctl_icmp_ignore_bogus_error_responses; | 195 | int sysctl_icmp_ignore_bogus_error_responses = 1; |
| 196 | 196 | ||
| 197 | /* | 197 | /* |
| 198 | * Configurable global rate limit. | 198 | * Configurable global rate limit. |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index abe23923e4e7..9981dcd68f11 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -830,7 +830,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 830 | skb->h.raw = skb->nh.raw; | 830 | skb->h.raw = skb->nh.raw; |
| 831 | skb->nh.raw = skb_push(skb, gre_hlen); | 831 | skb->nh.raw = skb_push(skb, gre_hlen); |
| 832 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 832 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
| 833 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED); | 833 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
| 834 | IPSKB_REROUTED); | ||
| 834 | dst_release(skb->dst); | 835 | dst_release(skb->dst); |
| 835 | skb->dst = &rt->u.dst; | 836 | skb->dst = &rt->u.dst; |
| 836 | 837 | ||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 3324fbfe528a..57d290d89ec2 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -207,8 +207,10 @@ static inline int ip_finish_output(struct sk_buff *skb) | |||
| 207 | { | 207 | { |
| 208 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) | 208 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) |
| 209 | /* Policy lookup after SNAT yielded a new policy */ | 209 | /* Policy lookup after SNAT yielded a new policy */ |
| 210 | if (skb->dst->xfrm != NULL) | 210 | if (skb->dst->xfrm != NULL) { |
| 211 | return xfrm4_output_finish(skb); | 211 | IPCB(skb)->flags |= IPSKB_REROUTED; |
| 212 | return dst_output(skb); | ||
| 213 | } | ||
| 212 | #endif | 214 | #endif |
| 213 | if (skb->len > dst_mtu(skb->dst) && | 215 | if (skb->len > dst_mtu(skb->dst) && |
| 214 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) | 216 | !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) |
| @@ -271,8 +273,9 @@ int ip_mc_output(struct sk_buff *skb) | |||
| 271 | newskb->dev, ip_dev_loopback_xmit); | 273 | newskb->dev, ip_dev_loopback_xmit); |
| 272 | } | 274 | } |
| 273 | 275 | ||
| 274 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, | 276 | return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, |
| 275 | ip_finish_output); | 277 | ip_finish_output, |
| 278 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | ||
| 276 | } | 279 | } |
| 277 | 280 | ||
| 278 | int ip_output(struct sk_buff *skb) | 281 | int ip_output(struct sk_buff *skb) |
| @@ -284,8 +287,9 @@ int ip_output(struct sk_buff *skb) | |||
| 284 | skb->dev = dev; | 287 | skb->dev = dev; |
| 285 | skb->protocol = htons(ETH_P_IP); | 288 | skb->protocol = htons(ETH_P_IP); |
| 286 | 289 | ||
| 287 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, | 290 | return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, |
| 288 | ip_finish_output); | 291 | ip_finish_output, |
| 292 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | ||
| 289 | } | 293 | } |
| 290 | 294 | ||
| 291 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) | 295 | int ip_queue_xmit(struct sk_buff *skb, int ipfragok) |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index e5cbe72c6b80..03d13742a4b8 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
| @@ -622,7 +622,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 622 | skb->h.raw = skb->nh.raw; | 622 | skb->h.raw = skb->nh.raw; |
| 623 | skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); | 623 | skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); |
| 624 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 624 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
| 625 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED); | 625 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
| 626 | IPSKB_REROUTED); | ||
| 626 | dst_release(skb->dst); | 627 | dst_release(skb->dst); |
| 627 | skb->dst = &rt->u.dst; | 628 | skb->dst = &rt->u.dst; |
| 628 | 629 | ||
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 52a3d7c57907..ed42cdc57cd9 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
| @@ -78,6 +78,47 @@ int ip_route_me_harder(struct sk_buff **pskb) | |||
| 78 | } | 78 | } |
| 79 | EXPORT_SYMBOL(ip_route_me_harder); | 79 | EXPORT_SYMBOL(ip_route_me_harder); |
| 80 | 80 | ||
| 81 | #ifdef CONFIG_XFRM | ||
| 82 | int ip_xfrm_me_harder(struct sk_buff **pskb) | ||
| 83 | { | ||
| 84 | struct flowi fl; | ||
| 85 | unsigned int hh_len; | ||
| 86 | struct dst_entry *dst; | ||
| 87 | |||
| 88 | if (IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) | ||
| 89 | return 0; | ||
| 90 | if (xfrm_decode_session(*pskb, &fl, AF_INET) < 0) | ||
| 91 | return -1; | ||
| 92 | |||
| 93 | dst = (*pskb)->dst; | ||
| 94 | if (dst->xfrm) | ||
| 95 | dst = ((struct xfrm_dst *)dst)->route; | ||
| 96 | dst_hold(dst); | ||
| 97 | |||
| 98 | if (xfrm_lookup(&dst, &fl, (*pskb)->sk, 0) < 0) | ||
| 99 | return -1; | ||
| 100 | |||
| 101 | dst_release((*pskb)->dst); | ||
| 102 | (*pskb)->dst = dst; | ||
| 103 | |||
| 104 | /* Change in oif may mean change in hh_len. */ | ||
| 105 | hh_len = (*pskb)->dst->dev->hard_header_len; | ||
| 106 | if (skb_headroom(*pskb) < hh_len) { | ||
| 107 | struct sk_buff *nskb; | ||
| 108 | |||
| 109 | nskb = skb_realloc_headroom(*pskb, hh_len); | ||
| 110 | if (!nskb) | ||
| 111 | return -1; | ||
| 112 | if ((*pskb)->sk) | ||
| 113 | skb_set_owner_w(nskb, (*pskb)->sk); | ||
| 114 | kfree_skb(*pskb); | ||
| 115 | *pskb = nskb; | ||
| 116 | } | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | EXPORT_SYMBOL(ip_xfrm_me_harder); | ||
| 120 | #endif | ||
| 121 | |||
| 81 | void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); | 122 | void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); |
| 82 | EXPORT_SYMBOL(ip_nat_decode_session); | 123 | EXPORT_SYMBOL(ip_nat_decode_session); |
| 83 | 124 | ||
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 92c54999a19d..7c3f7d380240 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
| @@ -235,19 +235,19 @@ ip_nat_out(unsigned int hooknum, | |||
| 235 | return NF_ACCEPT; | 235 | return NF_ACCEPT; |
| 236 | 236 | ||
| 237 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); | 237 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); |
| 238 | #ifdef CONFIG_XFRM | ||
| 238 | if (ret != NF_DROP && ret != NF_STOLEN | 239 | if (ret != NF_DROP && ret != NF_STOLEN |
| 239 | && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { | 240 | && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { |
| 240 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); | 241 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
| 241 | 242 | ||
| 242 | if (ct->tuplehash[dir].tuple.src.ip != | 243 | if (ct->tuplehash[dir].tuple.src.ip != |
| 243 | ct->tuplehash[!dir].tuple.dst.ip | 244 | ct->tuplehash[!dir].tuple.dst.ip |
| 244 | #ifdef CONFIG_XFRM | ||
| 245 | || ct->tuplehash[dir].tuple.src.u.all != | 245 | || ct->tuplehash[dir].tuple.src.u.all != |
| 246 | ct->tuplehash[!dir].tuple.dst.u.all | 246 | ct->tuplehash[!dir].tuple.dst.u.all |
| 247 | #endif | ||
| 248 | ) | 247 | ) |
| 249 | return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; | 248 | return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP; |
| 250 | } | 249 | } |
| 250 | #endif | ||
| 251 | return ret; | 251 | return ret; |
| 252 | } | 252 | } |
| 253 | 253 | ||
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 167619f638c6..6c8624a54933 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
| @@ -529,15 +529,10 @@ static int init_or_cleanup(int init) | |||
| 529 | goto cleanup_localinops; | 529 | goto cleanup_localinops; |
| 530 | } | 530 | } |
| 531 | #endif | 531 | #endif |
| 532 | |||
| 533 | /* For use by REJECT target */ | ||
| 534 | ip_ct_attach = __nf_conntrack_attach; | ||
| 535 | |||
| 536 | return ret; | 532 | return ret; |
| 537 | 533 | ||
| 538 | cleanup: | 534 | cleanup: |
| 539 | synchronize_net(); | 535 | synchronize_net(); |
| 540 | ip_ct_attach = NULL; | ||
| 541 | #ifdef CONFIG_SYSCTL | 536 | #ifdef CONFIG_SYSCTL |
| 542 | unregister_sysctl_table(nf_ct_ipv4_sysctl_header); | 537 | unregister_sysctl_table(nf_ct_ipv4_sysctl_header); |
| 543 | cleanup_localinops: | 538 | cleanup_localinops: |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index d4df0ddd424b..32ad229b4fed 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
| @@ -152,10 +152,16 @@ error_nolock: | |||
| 152 | goto out_exit; | 152 | goto out_exit; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | int xfrm4_output_finish(struct sk_buff *skb) | 155 | static int xfrm4_output_finish(struct sk_buff *skb) |
| 156 | { | 156 | { |
| 157 | int err; | 157 | int err; |
| 158 | 158 | ||
| 159 | #ifdef CONFIG_NETFILTER | ||
| 160 | if (!skb->dst->xfrm) { | ||
| 161 | IPCB(skb)->flags |= IPSKB_REROUTED; | ||
| 162 | return dst_output(skb); | ||
| 163 | } | ||
| 164 | #endif | ||
| 159 | while (likely((err = xfrm4_output_one(skb)) == 0)) { | 165 | while (likely((err = xfrm4_output_one(skb)) == 0)) { |
| 160 | nf_reset(skb); | 166 | nf_reset(skb); |
| 161 | 167 | ||
| @@ -178,6 +184,7 @@ int xfrm4_output_finish(struct sk_buff *skb) | |||
| 178 | 184 | ||
| 179 | int xfrm4_output(struct sk_buff *skb) | 185 | int xfrm4_output(struct sk_buff *skb) |
| 180 | { | 186 | { |
| 181 | return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, | 187 | return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, |
| 182 | xfrm4_output_finish); | 188 | xfrm4_output_finish, |
| 189 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | ||
| 183 | } | 190 | } |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index fcf883183cef..21eb725e885f 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include <linux/net.h> | 42 | #include <linux/net.h> |
| 43 | #include <linux/skbuff.h> | 43 | #include <linux/skbuff.h> |
| 44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
| 45 | #include <linux/netfilter.h> | ||
| 45 | 46 | ||
| 46 | #ifdef CONFIG_SYSCTL | 47 | #ifdef CONFIG_SYSCTL |
| 47 | #include <linux/sysctl.h> | 48 | #include <linux/sysctl.h> |
| @@ -255,6 +256,7 @@ out: | |||
| 255 | struct icmpv6_msg { | 256 | struct icmpv6_msg { |
| 256 | struct sk_buff *skb; | 257 | struct sk_buff *skb; |
| 257 | int offset; | 258 | int offset; |
| 259 | uint8_t type; | ||
| 258 | }; | 260 | }; |
| 259 | 261 | ||
| 260 | static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) | 262 | static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) |
| @@ -266,6 +268,8 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st | |||
| 266 | csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset, | 268 | csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset, |
| 267 | to, len, csum); | 269 | to, len, csum); |
| 268 | skb->csum = csum_block_add(skb->csum, csum, odd); | 270 | skb->csum = csum_block_add(skb->csum, csum, odd); |
| 271 | if (!(msg->type & ICMPV6_INFOMSG_MASK)) | ||
| 272 | nf_ct_attach(skb, org_skb); | ||
| 269 | return 0; | 273 | return 0; |
| 270 | } | 274 | } |
| 271 | 275 | ||
| @@ -403,6 +407,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, | |||
| 403 | 407 | ||
| 404 | msg.skb = skb; | 408 | msg.skb = skb; |
| 405 | msg.offset = skb->nh.raw - skb->data; | 409 | msg.offset = skb->nh.raw - skb->data; |
| 410 | msg.type = type; | ||
| 406 | 411 | ||
| 407 | len = skb->len - msg.offset; | 412 | len = skb->len - msg.offset; |
| 408 | len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr)); | 413 | len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr)); |
| @@ -500,6 +505,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
| 500 | 505 | ||
| 501 | msg.skb = skb; | 506 | msg.skb = skb; |
| 502 | msg.offset = 0; | 507 | msg.offset = 0; |
| 508 | msg.type = ICMPV6_ECHO_REPLY; | ||
| 503 | 509 | ||
| 504 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), | 510 | err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), |
| 505 | sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl, | 511 | sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl, |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index c745717b4ce2..0e6d1d4bbd5c 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
| @@ -160,6 +160,8 @@ static void send_reset(struct sk_buff *oldskb) | |||
| 160 | csum_partial((char *)tcph, | 160 | csum_partial((char *)tcph, |
| 161 | sizeof(struct tcphdr), 0)); | 161 | sizeof(struct tcphdr), 0)); |
| 162 | 162 | ||
| 163 | nf_ct_attach(nskb, oldskb); | ||
| 164 | |||
| 163 | NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev, | 165 | NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev, |
| 164 | dst_output); | 166 | dst_output); |
| 165 | } | 167 | } |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 738376cf0c51..ae20a0ec9bd8 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -803,10 +803,7 @@ back_from_confirm: | |||
| 803 | err = rawv6_push_pending_frames(sk, &fl, rp); | 803 | err = rawv6_push_pending_frames(sk, &fl, rp); |
| 804 | } | 804 | } |
| 805 | done: | 805 | done: |
| 806 | ip6_dst_store(sk, dst, | 806 | dst_release(dst); |
| 807 | ipv6_addr_equal(&fl.fl6_dst, &np->daddr) ? | ||
| 808 | &np->daddr : NULL); | ||
| 809 | |||
| 810 | release_sock(sk); | 807 | release_sock(sk); |
| 811 | out: | 808 | out: |
| 812 | fl6_sock_release(flowlabel); | 809 | fl6_sock_release(flowlabel); |
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 99c0a0fa4a97..a8e5544da93e 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
| @@ -102,8 +102,6 @@ config NF_CT_NETLINK | |||
| 102 | help | 102 | help |
| 103 | This option enables support for a netlink-based userspace interface | 103 | This option enables support for a netlink-based userspace interface |
| 104 | 104 | ||
| 105 | endmenu | ||
| 106 | |||
| 107 | config NETFILTER_XTABLES | 105 | config NETFILTER_XTABLES |
| 108 | tristate "Netfilter Xtables support (required for ip_tables)" | 106 | tristate "Netfilter Xtables support (required for ip_tables)" |
| 109 | help | 107 | help |
| @@ -128,7 +126,7 @@ config NETFILTER_XT_TARGET_CONNMARK | |||
| 128 | tristate '"CONNMARK" target support' | 126 | tristate '"CONNMARK" target support' |
| 129 | depends on NETFILTER_XTABLES | 127 | depends on NETFILTER_XTABLES |
| 130 | depends on IP_NF_MANGLE || IP6_NF_MANGLE | 128 | depends on IP_NF_MANGLE || IP6_NF_MANGLE |
| 131 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) | 129 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK) |
| 132 | help | 130 | help |
| 133 | This option adds a `CONNMARK' target, which allows one to manipulate | 131 | This option adds a `CONNMARK' target, which allows one to manipulate |
| 134 | the connection mark value. Similar to the MARK target, but | 132 | the connection mark value. Similar to the MARK target, but |
| @@ -189,7 +187,7 @@ config NETFILTER_XT_MATCH_COMMENT | |||
| 189 | config NETFILTER_XT_MATCH_CONNBYTES | 187 | config NETFILTER_XT_MATCH_CONNBYTES |
| 190 | tristate '"connbytes" per-connection counter match support' | 188 | tristate '"connbytes" per-connection counter match support' |
| 191 | depends on NETFILTER_XTABLES | 189 | depends on NETFILTER_XTABLES |
| 192 | depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || NF_CT_ACCT | 190 | depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK) |
| 193 | help | 191 | help |
| 194 | This option adds a `connbytes' match, which allows you to match the | 192 | This option adds a `connbytes' match, which allows you to match the |
| 195 | number of bytes and/or packets for each direction within a connection. | 193 | number of bytes and/or packets for each direction within a connection. |
| @@ -200,7 +198,7 @@ config NETFILTER_XT_MATCH_CONNBYTES | |||
| 200 | config NETFILTER_XT_MATCH_CONNMARK | 198 | config NETFILTER_XT_MATCH_CONNMARK |
| 201 | tristate '"connmark" connection mark match support' | 199 | tristate '"connmark" connection mark match support' |
| 202 | depends on NETFILTER_XTABLES | 200 | depends on NETFILTER_XTABLES |
| 203 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || NF_CONNTRACK_MARK | 201 | depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK) |
| 204 | help | 202 | help |
| 205 | This option adds a `connmark' match, which allows you to match the | 203 | This option adds a `connmark' match, which allows you to match the |
| 206 | connection mark value previously set for the session by `CONNMARK'. | 204 | connection mark value previously set for the session by `CONNMARK'. |
| @@ -361,3 +359,5 @@ config NETFILTER_XT_MATCH_TCPMSS | |||
| 361 | 359 | ||
| 362 | To compile it as a module, choose M here. If unsure, say N. | 360 | To compile it as a module, choose M here. If unsure, say N. |
| 363 | 361 | ||
| 362 | endmenu | ||
| 363 | |||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 0ce337a1d974..d622ddf08bb0 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -1556,6 +1556,8 @@ void nf_conntrack_cleanup(void) | |||
| 1556 | { | 1556 | { |
| 1557 | int i; | 1557 | int i; |
| 1558 | 1558 | ||
| 1559 | ip_ct_attach = NULL; | ||
| 1560 | |||
| 1559 | /* This makes sure all current packets have passed through | 1561 | /* This makes sure all current packets have passed through |
| 1560 | netfilter framework. Roll on, two-stage module | 1562 | netfilter framework. Roll on, two-stage module |
| 1561 | delete... */ | 1563 | delete... */ |
| @@ -1715,6 +1717,9 @@ int __init nf_conntrack_init(void) | |||
| 1715 | nf_ct_l3protos[i] = &nf_conntrack_generic_l3proto; | 1717 | nf_ct_l3protos[i] = &nf_conntrack_generic_l3proto; |
| 1716 | write_unlock_bh(&nf_conntrack_lock); | 1718 | write_unlock_bh(&nf_conntrack_lock); |
| 1717 | 1719 | ||
| 1720 | /* For use by REJECT target */ | ||
| 1721 | ip_ct_attach = __nf_conntrack_attach; | ||
| 1722 | |||
| 1718 | /* Set up fake conntrack: | 1723 | /* Set up fake conntrack: |
| 1719 | - to never be deleted, not in any hashes */ | 1724 | - to never be deleted, not in any hashes */ |
| 1720 | atomic_set(&nf_conntrack_untracked.ct_general.use, 1); | 1725 | atomic_set(&nf_conntrack_untracked.ct_general.use, 1); |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index df99138c3b3b..6492ed66fb3c 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
| @@ -864,7 +864,9 @@ static int csum6(const struct sk_buff *skb, unsigned int dataoff) | |||
| 864 | { | 864 | { |
| 865 | return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, | 865 | return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, |
| 866 | skb->len - dataoff, IPPROTO_TCP, | 866 | skb->len - dataoff, IPPROTO_TCP, |
| 867 | skb->ip_summed == CHECKSUM_HW ? skb->csum | 867 | skb->ip_summed == CHECKSUM_HW |
| 868 | ? csum_sub(skb->csum, | ||
| 869 | skb_checksum(skb, 0, dataoff, 0)) | ||
| 868 | : skb_checksum(skb, dataoff, skb->len - dataoff, | 870 | : skb_checksum(skb, dataoff, skb->len - dataoff, |
| 869 | 0)); | 871 | 0)); |
| 870 | } | 872 | } |
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index 4264dd079a16..831d206344e0 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c | |||
| @@ -161,7 +161,9 @@ static int csum6(const struct sk_buff *skb, unsigned int dataoff) | |||
| 161 | { | 161 | { |
| 162 | return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, | 162 | return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, |
| 163 | skb->len - dataoff, IPPROTO_UDP, | 163 | skb->len - dataoff, IPPROTO_UDP, |
| 164 | skb->ip_summed == CHECKSUM_HW ? skb->csum | 164 | skb->ip_summed == CHECKSUM_HW |
| 165 | ? csum_sub(skb->csum, | ||
| 166 | skb_checksum(skb, 0, dataoff, 0)) | ||
| 165 | : skb_checksum(skb, dataoff, skb->len - dataoff, | 167 | : skb_checksum(skb, dataoff, skb->len - dataoff, |
| 166 | 0)); | 168 | 0)); |
| 167 | } | 169 | } |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 4ae1538c54a9..43e72419c868 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
| @@ -238,7 +238,7 @@ int genl_register_family(struct genl_family *family) | |||
| 238 | sizeof(struct nlattr *), GFP_KERNEL); | 238 | sizeof(struct nlattr *), GFP_KERNEL); |
| 239 | if (family->attrbuf == NULL) { | 239 | if (family->attrbuf == NULL) { |
| 240 | err = -ENOMEM; | 240 | err = -ENOMEM; |
| 241 | goto errout; | 241 | goto errout_locked; |
| 242 | } | 242 | } |
| 243 | } else | 243 | } else |
| 244 | family->attrbuf = NULL; | 244 | family->attrbuf = NULL; |
| @@ -288,7 +288,7 @@ int genl_unregister_family(struct genl_family *family) | |||
| 288 | return -ENOENT; | 288 | return -ENOENT; |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | static inline int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, | 291 | static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, |
| 292 | int *errp) | 292 | int *errp) |
| 293 | { | 293 | { |
| 294 | struct genl_ops *ops; | 294 | struct genl_ops *ops; |
| @@ -375,7 +375,7 @@ static void genl_rcv(struct sock *sk, int len) | |||
| 375 | do { | 375 | do { |
| 376 | if (genl_trylock()) | 376 | if (genl_trylock()) |
| 377 | return; | 377 | return; |
| 378 | netlink_run_queue(sk, &qlen, &genl_rcv_msg); | 378 | netlink_run_queue(sk, &qlen, genl_rcv_msg); |
| 379 | genl_unlock(); | 379 | genl_unlock(); |
| 380 | } while (qlen && genl_sock && genl_sock->sk_receive_queue.qlen); | 380 | } while (qlen && genl_sock && genl_sock->sk_receive_queue.qlen); |
| 381 | } | 381 | } |
| @@ -549,10 +549,8 @@ static int __init genl_init(void) | |||
| 549 | netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); | 549 | netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); |
| 550 | genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID, | 550 | genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID, |
| 551 | genl_rcv, THIS_MODULE); | 551 | genl_rcv, THIS_MODULE); |
| 552 | if (genl_sock == NULL) { | 552 | if (genl_sock == NULL) |
| 553 | panic("GENL: Cannot initialize generic netlink\n"); | 553 | panic("GENL: Cannot initialize generic netlink\n"); |
| 554 | return -ENOMEM; | ||
| 555 | } | ||
| 556 | 554 | ||
| 557 | return 0; | 555 | return 0; |
| 558 | 556 | ||
| @@ -560,7 +558,6 @@ errout_register: | |||
| 560 | genl_unregister_family(&genl_ctrl); | 558 | genl_unregister_family(&genl_ctrl); |
| 561 | errout: | 559 | errout: |
| 562 | panic("GENL: Cannot register controller: %d\n", err); | 560 | panic("GENL: Cannot register controller: %d\n", err); |
| 563 | return err; | ||
| 564 | } | 561 | } |
| 565 | 562 | ||
| 566 | subsys_initcall(genl_init); | 563 | subsys_initcall(genl_init); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index dbf4620768d6..98ec53bd3ac7 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -889,7 +889,9 @@ restart: | |||
| 889 | xfrm_pol_put(policy); | 889 | xfrm_pol_put(policy); |
| 890 | if (dst) | 890 | if (dst) |
| 891 | dst_free(dst); | 891 | dst_free(dst); |
| 892 | goto restart; | 892 | |
| 893 | err = -EHOSTUNREACH; | ||
| 894 | goto error; | ||
| 893 | } | 895 | } |
| 894 | dst->next = policy->bundles; | 896 | dst->next = policy->bundles; |
| 895 | policy->bundles = dst; | 897 | policy->bundles = dst; |
