diff options
Diffstat (limited to 'net')
40 files changed, 223 insertions, 169 deletions
diff --git a/net/atm/atm_misc.c b/net/atm/atm_misc.c index 223c7ad5bd0f..02cc7e71efea 100644 --- a/net/atm/atm_misc.c +++ b/net/atm/atm_misc.c | |||
| @@ -74,11 +74,14 @@ struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, | |||
| 74 | */ | 74 | */ |
| 75 | 75 | ||
| 76 | 76 | ||
| 77 | int atm_pcr_goal(struct atm_trafprm *tp) | 77 | int atm_pcr_goal(const struct atm_trafprm *tp) |
| 78 | { | 78 | { |
| 79 | if (tp->pcr && tp->pcr != ATM_MAX_PCR) return -tp->pcr; | 79 | if (tp->pcr && tp->pcr != ATM_MAX_PCR) |
| 80 | if (tp->min_pcr && !tp->pcr) return tp->min_pcr; | 80 | return -tp->pcr; |
| 81 | if (tp->max_pcr != ATM_MAX_PCR) return -tp->max_pcr; | 81 | if (tp->min_pcr && !tp->pcr) |
| 82 | return tp->min_pcr; | ||
| 83 | if (tp->max_pcr != ATM_MAX_PCR) | ||
| 84 | return -tp->max_pcr; | ||
| 82 | return 0; | 85 | return 0; |
| 83 | } | 86 | } |
| 84 | 87 | ||
diff --git a/net/atm/common.c b/net/atm/common.c index 63feea49fb13..6656b111cc05 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
| @@ -221,6 +221,29 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) | |||
| 221 | EXPORT_SYMBOL(vcc_release_async); | 221 | EXPORT_SYMBOL(vcc_release_async); |
| 222 | 222 | ||
| 223 | 223 | ||
| 224 | void atm_dev_release_vccs(struct atm_dev *dev) | ||
| 225 | { | ||
| 226 | int i; | ||
| 227 | |||
| 228 | write_lock_irq(&vcc_sklist_lock); | ||
| 229 | for (i = 0; i < VCC_HTABLE_SIZE; i++) { | ||
| 230 | struct hlist_head *head = &vcc_hash[i]; | ||
| 231 | struct hlist_node *node, *tmp; | ||
| 232 | struct sock *s; | ||
| 233 | struct atm_vcc *vcc; | ||
| 234 | |||
| 235 | sk_for_each_safe(s, node, tmp, head) { | ||
| 236 | vcc = atm_sk(s); | ||
| 237 | if (vcc->dev == dev) { | ||
| 238 | vcc_release_async(vcc, -EPIPE); | ||
| 239 | sk_del_node_init(s); | ||
| 240 | } | ||
| 241 | } | ||
| 242 | } | ||
| 243 | write_unlock_irq(&vcc_sklist_lock); | ||
| 244 | } | ||
| 245 | |||
| 246 | |||
| 224 | static int adjust_tp(struct atm_trafprm *tp,unsigned char aal) | 247 | static int adjust_tp(struct atm_trafprm *tp,unsigned char aal) |
| 225 | { | 248 | { |
| 226 | int max_sdu; | 249 | int max_sdu; |
| @@ -332,12 +355,13 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi, | |||
| 332 | return -EINVAL; | 355 | return -EINVAL; |
| 333 | if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE)) | 356 | if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE)) |
| 334 | return -EPERM; | 357 | return -EPERM; |
| 335 | error = 0; | 358 | error = -ENODEV; |
| 336 | if (!try_module_get(dev->ops->owner)) | 359 | if (!try_module_get(dev->ops->owner)) |
| 337 | return -ENODEV; | 360 | return error; |
| 338 | vcc->dev = dev; | 361 | vcc->dev = dev; |
| 339 | write_lock_irq(&vcc_sklist_lock); | 362 | write_lock_irq(&vcc_sklist_lock); |
| 340 | if ((error = find_ci(vcc, &vpi, &vci))) { | 363 | if (test_bit(ATM_DF_REMOVED, &dev->flags) || |
| 364 | (error = find_ci(vcc, &vpi, &vci))) { | ||
| 341 | write_unlock_irq(&vcc_sklist_lock); | 365 | write_unlock_irq(&vcc_sklist_lock); |
| 342 | goto fail_module_put; | 366 | goto fail_module_put; |
| 343 | } | 367 | } |
| @@ -423,33 +447,23 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci) | |||
| 423 | if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS || | 447 | if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS || |
| 424 | vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) | 448 | vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) |
| 425 | return -EINVAL; | 449 | return -EINVAL; |
| 426 | if (itf != ATM_ITF_ANY) { | 450 | if (likely(itf != ATM_ITF_ANY)) { |
| 427 | dev = atm_dev_lookup(itf); | 451 | dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf); |
| 428 | if (!dev) | ||
| 429 | return -ENODEV; | ||
| 430 | error = __vcc_connect(vcc, dev, vpi, vci); | ||
| 431 | if (error) { | ||
| 432 | atm_dev_put(dev); | ||
| 433 | return error; | ||
| 434 | } | ||
| 435 | } else { | 452 | } else { |
| 436 | struct list_head *p, *next; | ||
| 437 | |||
| 438 | dev = NULL; | 453 | dev = NULL; |
| 439 | spin_lock(&atm_dev_lock); | 454 | down(&atm_dev_mutex); |
| 440 | list_for_each_safe(p, next, &atm_devs) { | 455 | if (!list_empty(&atm_devs)) { |
| 441 | dev = list_entry(p, struct atm_dev, dev_list); | 456 | dev = list_entry(atm_devs.next, struct atm_dev, dev_list); |
| 442 | atm_dev_hold(dev); | 457 | atm_dev_hold(dev); |
| 443 | spin_unlock(&atm_dev_lock); | ||
| 444 | if (!__vcc_connect(vcc, dev, vpi, vci)) | ||
| 445 | break; | ||
| 446 | atm_dev_put(dev); | ||
| 447 | dev = NULL; | ||
| 448 | spin_lock(&atm_dev_lock); | ||
| 449 | } | 458 | } |
| 450 | spin_unlock(&atm_dev_lock); | 459 | up(&atm_dev_mutex); |
| 451 | if (!dev) | 460 | } |
| 452 | return -ENODEV; | 461 | if (!dev) |
| 462 | return -ENODEV; | ||
| 463 | error = __vcc_connect(vcc, dev, vpi, vci); | ||
| 464 | if (error) { | ||
| 465 | atm_dev_put(dev); | ||
| 466 | return error; | ||
| 453 | } | 467 | } |
| 454 | if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) | 468 | if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) |
| 455 | set_bit(ATM_VF_PARTIAL,&vcc->flags); | 469 | set_bit(ATM_VF_PARTIAL,&vcc->flags); |
diff --git a/net/atm/common.h b/net/atm/common.h index e49ed41c0e33..4887c317cefe 100644 --- a/net/atm/common.h +++ b/net/atm/common.h | |||
| @@ -47,4 +47,6 @@ static inline void atm_proc_exit(void) | |||
| 47 | /* SVC */ | 47 | /* SVC */ |
| 48 | int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos); | 48 | int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos); |
| 49 | 49 | ||
| 50 | void atm_dev_release_vccs(struct atm_dev *dev); | ||
| 51 | |||
| 50 | #endif | 52 | #endif |
diff --git a/net/atm/resources.c b/net/atm/resources.c index 415d2615d475..c8c459fcb038 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | LIST_HEAD(atm_devs); | 27 | LIST_HEAD(atm_devs); |
| 28 | DEFINE_SPINLOCK(atm_dev_lock); | 28 | DECLARE_MUTEX(atm_dev_mutex); |
| 29 | 29 | ||
| 30 | static struct atm_dev *__alloc_atm_dev(const char *type) | 30 | static struct atm_dev *__alloc_atm_dev(const char *type) |
| 31 | { | 31 | { |
| @@ -52,7 +52,7 @@ static struct atm_dev *__atm_dev_lookup(int number) | |||
| 52 | 52 | ||
| 53 | list_for_each(p, &atm_devs) { | 53 | list_for_each(p, &atm_devs) { |
| 54 | dev = list_entry(p, struct atm_dev, dev_list); | 54 | dev = list_entry(p, struct atm_dev, dev_list); |
| 55 | if ((dev->ops) && (dev->number == number)) { | 55 | if (dev->number == number) { |
| 56 | atm_dev_hold(dev); | 56 | atm_dev_hold(dev); |
| 57 | return dev; | 57 | return dev; |
| 58 | } | 58 | } |
| @@ -64,12 +64,13 @@ struct atm_dev *atm_dev_lookup(int number) | |||
| 64 | { | 64 | { |
| 65 | struct atm_dev *dev; | 65 | struct atm_dev *dev; |
| 66 | 66 | ||
| 67 | spin_lock(&atm_dev_lock); | 67 | down(&atm_dev_mutex); |
| 68 | dev = __atm_dev_lookup(number); | 68 | dev = __atm_dev_lookup(number); |
| 69 | spin_unlock(&atm_dev_lock); | 69 | up(&atm_dev_mutex); |
| 70 | return dev; | 70 | return dev; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | |||
| 73 | struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | 74 | struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, |
| 74 | int number, unsigned long *flags) | 75 | int number, unsigned long *flags) |
| 75 | { | 76 | { |
| @@ -81,11 +82,11 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | |||
| 81 | type); | 82 | type); |
| 82 | return NULL; | 83 | return NULL; |
| 83 | } | 84 | } |
| 84 | spin_lock(&atm_dev_lock); | 85 | down(&atm_dev_mutex); |
| 85 | if (number != -1) { | 86 | if (number != -1) { |
| 86 | if ((inuse = __atm_dev_lookup(number))) { | 87 | if ((inuse = __atm_dev_lookup(number))) { |
| 87 | atm_dev_put(inuse); | 88 | atm_dev_put(inuse); |
| 88 | spin_unlock(&atm_dev_lock); | 89 | up(&atm_dev_mutex); |
| 89 | kfree(dev); | 90 | kfree(dev); |
| 90 | return NULL; | 91 | return NULL; |
| 91 | } | 92 | } |
| @@ -105,19 +106,17 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | |||
| 105 | memset(&dev->flags, 0, sizeof(dev->flags)); | 106 | memset(&dev->flags, 0, sizeof(dev->flags)); |
| 106 | memset(&dev->stats, 0, sizeof(dev->stats)); | 107 | memset(&dev->stats, 0, sizeof(dev->stats)); |
| 107 | atomic_set(&dev->refcnt, 1); | 108 | atomic_set(&dev->refcnt, 1); |
| 108 | list_add_tail(&dev->dev_list, &atm_devs); | ||
| 109 | spin_unlock(&atm_dev_lock); | ||
| 110 | 109 | ||
| 111 | if (atm_proc_dev_register(dev) < 0) { | 110 | if (atm_proc_dev_register(dev) < 0) { |
| 112 | printk(KERN_ERR "atm_dev_register: " | 111 | printk(KERN_ERR "atm_dev_register: " |
| 113 | "atm_proc_dev_register failed for dev %s\n", | 112 | "atm_proc_dev_register failed for dev %s\n", |
| 114 | type); | 113 | type); |
| 115 | spin_lock(&atm_dev_lock); | 114 | up(&atm_dev_mutex); |
| 116 | list_del(&dev->dev_list); | ||
| 117 | spin_unlock(&atm_dev_lock); | ||
| 118 | kfree(dev); | 115 | kfree(dev); |
| 119 | return NULL; | 116 | return NULL; |
| 120 | } | 117 | } |
| 118 | list_add_tail(&dev->dev_list, &atm_devs); | ||
| 119 | up(&atm_dev_mutex); | ||
| 121 | 120 | ||
| 122 | return dev; | 121 | return dev; |
| 123 | } | 122 | } |
| @@ -125,37 +124,22 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | |||
| 125 | 124 | ||
| 126 | void atm_dev_deregister(struct atm_dev *dev) | 125 | void atm_dev_deregister(struct atm_dev *dev) |
| 127 | { | 126 | { |
| 128 | unsigned long warning_time; | 127 | BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags)); |
| 128 | set_bit(ATM_DF_REMOVED, &dev->flags); | ||
| 129 | |||
| 130 | /* | ||
| 131 | * if we remove current device from atm_devs list, new device | ||
| 132 | * with same number can appear, such we need deregister proc, | ||
| 133 | * release async all vccs and remove them from vccs list too | ||
| 134 | */ | ||
| 135 | down(&atm_dev_mutex); | ||
| 136 | list_del(&dev->dev_list); | ||
| 137 | up(&atm_dev_mutex); | ||
| 129 | 138 | ||
| 139 | atm_dev_release_vccs(dev); | ||
| 130 | atm_proc_dev_deregister(dev); | 140 | atm_proc_dev_deregister(dev); |
| 131 | 141 | ||
| 132 | spin_lock(&atm_dev_lock); | 142 | atm_dev_put(dev); |
| 133 | list_del(&dev->dev_list); | ||
| 134 | spin_unlock(&atm_dev_lock); | ||
| 135 | |||
| 136 | warning_time = jiffies; | ||
| 137 | while (atomic_read(&dev->refcnt) != 1) { | ||
| 138 | msleep(250); | ||
| 139 | if ((jiffies - warning_time) > 10 * HZ) { | ||
| 140 | printk(KERN_EMERG "atm_dev_deregister: waiting for " | ||
| 141 | "dev %d to become free. Usage count = %d\n", | ||
| 142 | dev->number, atomic_read(&dev->refcnt)); | ||
| 143 | warning_time = jiffies; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | kfree(dev); | ||
| 148 | } | ||
| 149 | |||
| 150 | void shutdown_atm_dev(struct atm_dev *dev) | ||
| 151 | { | ||
| 152 | if (atomic_read(&dev->refcnt) > 1) { | ||
| 153 | set_bit(ATM_DF_CLOSE, &dev->flags); | ||
| 154 | return; | ||
| 155 | } | ||
| 156 | if (dev->ops->dev_close) | ||
| 157 | dev->ops->dev_close(dev); | ||
| 158 | atm_dev_deregister(dev); | ||
| 159 | } | 143 | } |
| 160 | 144 | ||
| 161 | 145 | ||
| @@ -211,16 +195,16 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg) | |||
| 211 | return -EFAULT; | 195 | return -EFAULT; |
| 212 | if (get_user(len, &iobuf->length)) | 196 | if (get_user(len, &iobuf->length)) |
| 213 | return -EFAULT; | 197 | return -EFAULT; |
| 214 | spin_lock(&atm_dev_lock); | 198 | down(&atm_dev_mutex); |
| 215 | list_for_each(p, &atm_devs) | 199 | list_for_each(p, &atm_devs) |
| 216 | size += sizeof(int); | 200 | size += sizeof(int); |
| 217 | if (size > len) { | 201 | if (size > len) { |
| 218 | spin_unlock(&atm_dev_lock); | 202 | up(&atm_dev_mutex); |
| 219 | return -E2BIG; | 203 | return -E2BIG; |
| 220 | } | 204 | } |
| 221 | tmp_buf = kmalloc(size, GFP_ATOMIC); | 205 | tmp_buf = kmalloc(size, GFP_ATOMIC); |
| 222 | if (!tmp_buf) { | 206 | if (!tmp_buf) { |
| 223 | spin_unlock(&atm_dev_lock); | 207 | up(&atm_dev_mutex); |
| 224 | return -ENOMEM; | 208 | return -ENOMEM; |
| 225 | } | 209 | } |
| 226 | tmp_p = tmp_buf; | 210 | tmp_p = tmp_buf; |
| @@ -228,7 +212,7 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg) | |||
| 228 | dev = list_entry(p, struct atm_dev, dev_list); | 212 | dev = list_entry(p, struct atm_dev, dev_list); |
| 229 | *tmp_p++ = dev->number; | 213 | *tmp_p++ = dev->number; |
| 230 | } | 214 | } |
| 231 | spin_unlock(&atm_dev_lock); | 215 | up(&atm_dev_mutex); |
| 232 | error = ((copy_to_user(buf, tmp_buf, size)) || | 216 | error = ((copy_to_user(buf, tmp_buf, size)) || |
| 233 | put_user(size, &iobuf->length)) | 217 | put_user(size, &iobuf->length)) |
| 234 | ? -EFAULT : 0; | 218 | ? -EFAULT : 0; |
| @@ -245,7 +229,8 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg) | |||
| 245 | if (get_user(number, &sioc->number)) | 229 | if (get_user(number, &sioc->number)) |
| 246 | return -EFAULT; | 230 | return -EFAULT; |
| 247 | 231 | ||
| 248 | if (!(dev = atm_dev_lookup(number))) | 232 | if (!(dev = try_then_request_module(atm_dev_lookup(number), |
| 233 | "atm-device-%d", number))) | ||
| 249 | return -ENODEV; | 234 | return -ENODEV; |
| 250 | 235 | ||
| 251 | switch (cmd) { | 236 | switch (cmd) { |
| @@ -414,13 +399,13 @@ static __inline__ void *dev_get_idx(loff_t left) | |||
| 414 | 399 | ||
| 415 | void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos) | 400 | void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos) |
| 416 | { | 401 | { |
| 417 | spin_lock(&atm_dev_lock); | 402 | down(&atm_dev_mutex); |
| 418 | return *pos ? dev_get_idx(*pos) : (void *) 1; | 403 | return *pos ? dev_get_idx(*pos) : (void *) 1; |
| 419 | } | 404 | } |
| 420 | 405 | ||
| 421 | void atm_dev_seq_stop(struct seq_file *seq, void *v) | 406 | void atm_dev_seq_stop(struct seq_file *seq, void *v) |
| 422 | { | 407 | { |
| 423 | spin_unlock(&atm_dev_lock); | 408 | up(&atm_dev_mutex); |
| 424 | } | 409 | } |
| 425 | 410 | ||
| 426 | void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 411 | void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
| @@ -434,4 +419,3 @@ void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
| 434 | EXPORT_SYMBOL(atm_dev_register); | 419 | EXPORT_SYMBOL(atm_dev_register); |
| 435 | EXPORT_SYMBOL(atm_dev_deregister); | 420 | EXPORT_SYMBOL(atm_dev_deregister); |
| 436 | EXPORT_SYMBOL(atm_dev_lookup); | 421 | EXPORT_SYMBOL(atm_dev_lookup); |
| 437 | EXPORT_SYMBOL(shutdown_atm_dev); | ||
diff --git a/net/atm/resources.h b/net/atm/resources.h index 12910619dbb6..b7fb82a93b42 100644 --- a/net/atm/resources.h +++ b/net/atm/resources.h | |||
| @@ -11,8 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | extern struct list_head atm_devs; | 13 | extern struct list_head atm_devs; |
| 14 | extern spinlock_t atm_dev_lock; | 14 | extern struct semaphore atm_dev_mutex; |
| 15 | |||
| 16 | 15 | ||
| 17 | int atm_dev_ioctl(unsigned int cmd, void __user *arg); | 16 | int atm_dev_ioctl(unsigned int cmd, void __user *arg); |
| 18 | 17 | ||
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index eaa150c33b04..d368cf249000 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -228,13 +228,14 @@ static int inet_create(struct socket *sock, int protocol) | |||
| 228 | unsigned char answer_flags; | 228 | unsigned char answer_flags; |
| 229 | char answer_no_check; | 229 | char answer_no_check; |
| 230 | int try_loading_module = 0; | 230 | int try_loading_module = 0; |
| 231 | int err = -ESOCKTNOSUPPORT; | 231 | int err; |
| 232 | 232 | ||
| 233 | sock->state = SS_UNCONNECTED; | 233 | sock->state = SS_UNCONNECTED; |
| 234 | 234 | ||
| 235 | /* Look for the requested type/protocol pair. */ | 235 | /* Look for the requested type/protocol pair. */ |
| 236 | answer = NULL; | 236 | answer = NULL; |
| 237 | lookup_protocol: | 237 | lookup_protocol: |
| 238 | err = -ESOCKTNOSUPPORT; | ||
| 238 | rcu_read_lock(); | 239 | rcu_read_lock(); |
| 239 | list_for_each_rcu(p, &inetsw[sock->type]) { | 240 | list_for_each_rcu(p, &inetsw[sock->type]) { |
| 240 | answer = list_entry(p, struct inet_protosw, list); | 241 | answer = list_entry(p, struct inet_protosw, list); |
| @@ -252,6 +253,7 @@ lookup_protocol: | |||
| 252 | if (IPPROTO_IP == answer->protocol) | 253 | if (IPPROTO_IP == answer->protocol) |
| 253 | break; | 254 | break; |
| 254 | } | 255 | } |
| 256 | err = -EPROTONOSUPPORT; | ||
| 255 | answer = NULL; | 257 | answer = NULL; |
| 256 | } | 258 | } |
| 257 | 259 | ||
| @@ -280,9 +282,6 @@ lookup_protocol: | |||
| 280 | err = -EPERM; | 282 | err = -EPERM; |
| 281 | if (answer->capability > 0 && !capable(answer->capability)) | 283 | if (answer->capability > 0 && !capable(answer->capability)) |
| 282 | goto out_rcu_unlock; | 284 | goto out_rcu_unlock; |
| 283 | err = -EPROTONOSUPPORT; | ||
| 284 | if (!protocol) | ||
| 285 | goto out_rcu_unlock; | ||
| 286 | 285 | ||
| 287 | sock->ops = answer->ops; | 286 | sock->ops = answer->ops; |
| 288 | answer_prot = answer->prot; | 287 | answer_prot = answer->prot; |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 882f88f6d13b..19b1b984d687 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -544,12 +544,16 @@ static void nl_fib_input(struct sock *sk, int len) | |||
| 544 | struct sk_buff *skb = NULL; | 544 | struct sk_buff *skb = NULL; |
| 545 | struct nlmsghdr *nlh = NULL; | 545 | struct nlmsghdr *nlh = NULL; |
| 546 | struct fib_result_nl *frn; | 546 | struct fib_result_nl *frn; |
| 547 | int err; | ||
| 548 | u32 pid; | 547 | u32 pid; |
| 549 | struct fib_table *tb; | 548 | struct fib_table *tb; |
| 550 | 549 | ||
| 551 | skb = skb_recv_datagram(sk, 0, 0, &err); | 550 | skb = skb_dequeue(&sk->sk_receive_queue); |
| 552 | nlh = (struct nlmsghdr *)skb->data; | 551 | nlh = (struct nlmsghdr *)skb->data; |
| 552 | if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len || | ||
| 553 | nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) { | ||
| 554 | kfree_skb(skb); | ||
| 555 | return; | ||
| 556 | } | ||
| 553 | 557 | ||
| 554 | frn = (struct fib_result_nl *) NLMSG_DATA(nlh); | 558 | frn = (struct fib_result_nl *) NLMSG_DATA(nlh); |
| 555 | tb = fib_get_table(frn->tb_id_in); | 559 | tb = fib_get_table(frn->tb_id_in); |
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 2a8c9afc3695..7ea0209cb169 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
| @@ -975,7 +975,7 @@ static void fib_seq_stop(struct seq_file *seq, void *v) | |||
| 975 | 975 | ||
| 976 | static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi) | 976 | static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi) |
| 977 | { | 977 | { |
| 978 | static unsigned type2flags[RTN_MAX + 1] = { | 978 | static const unsigned type2flags[RTN_MAX + 1] = { |
| 979 | [7] = RTF_REJECT, [8] = RTF_REJECT, | 979 | [7] = RTF_REJECT, [8] = RTF_REJECT, |
| 980 | }; | 980 | }; |
| 981 | unsigned flags = type2flags[type]; | 981 | unsigned flags = type2flags[type]; |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 186f20c4a45e..6d2a6ac070e3 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
| @@ -83,7 +83,7 @@ for (nhsel=0; nhsel < 1; nhsel++) | |||
| 83 | #define endfor_nexthops(fi) } | 83 | #define endfor_nexthops(fi) } |
| 84 | 84 | ||
| 85 | 85 | ||
| 86 | static struct | 86 | static const struct |
| 87 | { | 87 | { |
| 88 | int error; | 88 | int error; |
| 89 | u8 scope; | 89 | u8 scope; |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index e3eceecd0496..92e23b2ad4d2 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -220,7 +220,7 @@ struct icmp_control { | |||
| 220 | short error; /* This ICMP is classed as an error message */ | 220 | short error; /* This ICMP is classed as an error message */ |
| 221 | }; | 221 | }; |
| 222 | 222 | ||
| 223 | static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; | 223 | static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; |
| 224 | 224 | ||
| 225 | /* | 225 | /* |
| 226 | * The ICMP socket(s). This is the most convenient way to flow control | 226 | * The ICMP socket(s). This is the most convenient way to flow control |
| @@ -994,7 +994,7 @@ error: | |||
| 994 | /* | 994 | /* |
| 995 | * This table is the definition of how we handle ICMP. | 995 | * This table is the definition of how we handle ICMP. |
| 996 | */ | 996 | */ |
| 997 | static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { | 997 | static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { |
| 998 | [ICMP_ECHOREPLY] = { | 998 | [ICMP_ECHOREPLY] = { |
| 999 | .output_entry = ICMP_MIB_OUTECHOREPS, | 999 | .output_entry = ICMP_MIB_OUTECHOREPS, |
| 1000 | .input_entry = ICMP_MIB_INECHOREPS, | 1000 | .input_entry = ICMP_MIB_INECHOREPS, |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index c04607b49212..4a195c724f01 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
| @@ -897,7 +897,10 @@ int igmp_rcv(struct sk_buff *skb) | |||
| 897 | /* Is it our report looped back? */ | 897 | /* Is it our report looped back? */ |
| 898 | if (((struct rtable*)skb->dst)->fl.iif == 0) | 898 | if (((struct rtable*)skb->dst)->fl.iif == 0) |
| 899 | break; | 899 | break; |
| 900 | igmp_heard_report(in_dev, ih->group); | 900 | /* don't rely on MC router hearing unicast reports */ |
| 901 | if (skb->pkt_type == PACKET_MULTICAST || | ||
| 902 | skb->pkt_type == PACKET_BROADCAST) | ||
| 903 | igmp_heard_report(in_dev, ih->group); | ||
| 901 | break; | 904 | break; |
| 902 | case IGMP_PIM: | 905 | case IGMP_PIM: |
| 903 | #ifdef CONFIG_IP_PIMSM_V1 | 906 | #ifdef CONFIG_IP_PIMSM_V1 |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 4e9c74b54b15..a4c347c3b8e3 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -1217,7 +1217,7 @@ static int ipgre_tunnel_init(struct net_device *dev) | |||
| 1217 | return 0; | 1217 | return 0; |
| 1218 | } | 1218 | } |
| 1219 | 1219 | ||
| 1220 | int __init ipgre_fb_tunnel_init(struct net_device *dev) | 1220 | static int __init ipgre_fb_tunnel_init(struct net_device *dev) |
| 1221 | { | 1221 | { |
| 1222 | struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv; | 1222 | struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv; |
| 1223 | struct iphdr *iph = &tunnel->parms.iph; | 1223 | struct iphdr *iph = &tunnel->parms.iph; |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 11c2f68254f0..eba64e2bd397 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -690,7 +690,7 @@ csum_page(struct page *page, int offset, int copy) | |||
| 690 | return csum; | 690 | return csum; |
| 691 | } | 691 | } |
| 692 | 692 | ||
| 693 | inline int ip_ufo_append_data(struct sock *sk, | 693 | static inline int ip_ufo_append_data(struct sock *sk, |
| 694 | int getfrag(void *from, char *to, int offset, int len, | 694 | int getfrag(void *from, char *to, int offset, int len, |
| 695 | int odd, struct sk_buff *skb), | 695 | int odd, struct sk_buff *skb), |
| 696 | void *from, int length, int hh_len, int fragheaderlen, | 696 | void *from, int length, int hh_len, int fragheaderlen, |
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index f828fa2eb7de..2a3a8c59c655 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c | |||
| @@ -771,7 +771,7 @@ static inline int todrop_entry(struct ip_vs_conn *cp) | |||
| 771 | * The drop rate array needs tuning for real environments. | 771 | * The drop rate array needs tuning for real environments. |
| 772 | * Called from timer bh only => no locking | 772 | * Called from timer bh only => no locking |
| 773 | */ | 773 | */ |
| 774 | static char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; | 774 | static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; |
| 775 | static char todrop_counter[9] = {0}; | 775 | static char todrop_counter[9] = {0}; |
| 776 | int i; | 776 | int i; |
| 777 | 777 | ||
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index 2d66848e7aa0..9bdcf31b760e 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c | |||
| @@ -1909,7 +1909,7 @@ static int ip_vs_set_timeout(struct ip_vs_timeout_user *u) | |||
| 1909 | #define DAEMON_ARG_LEN (sizeof(struct ip_vs_daemon_user)) | 1909 | #define DAEMON_ARG_LEN (sizeof(struct ip_vs_daemon_user)) |
| 1910 | #define MAX_ARG_LEN SVCDEST_ARG_LEN | 1910 | #define MAX_ARG_LEN SVCDEST_ARG_LEN |
| 1911 | 1911 | ||
| 1912 | static unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = { | 1912 | static const unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = { |
| 1913 | [SET_CMDID(IP_VS_SO_SET_ADD)] = SERVICE_ARG_LEN, | 1913 | [SET_CMDID(IP_VS_SO_SET_ADD)] = SERVICE_ARG_LEN, |
| 1914 | [SET_CMDID(IP_VS_SO_SET_EDIT)] = SERVICE_ARG_LEN, | 1914 | [SET_CMDID(IP_VS_SO_SET_EDIT)] = SERVICE_ARG_LEN, |
| 1915 | [SET_CMDID(IP_VS_SO_SET_DEL)] = SERVICE_ARG_LEN, | 1915 | [SET_CMDID(IP_VS_SO_SET_DEL)] = SERVICE_ARG_LEN, |
| @@ -2180,7 +2180,7 @@ __ip_vs_get_timeouts(struct ip_vs_timeout_user *u) | |||
| 2180 | #define GET_TIMEOUT_ARG_LEN (sizeof(struct ip_vs_timeout_user)) | 2180 | #define GET_TIMEOUT_ARG_LEN (sizeof(struct ip_vs_timeout_user)) |
| 2181 | #define GET_DAEMON_ARG_LEN (sizeof(struct ip_vs_daemon_user) * 2) | 2181 | #define GET_DAEMON_ARG_LEN (sizeof(struct ip_vs_daemon_user) * 2) |
| 2182 | 2182 | ||
| 2183 | static unsigned char get_arglen[GET_CMDID(IP_VS_SO_GET_MAX)+1] = { | 2183 | static const unsigned char get_arglen[GET_CMDID(IP_VS_SO_GET_MAX)+1] = { |
| 2184 | [GET_CMDID(IP_VS_SO_GET_VERSION)] = 64, | 2184 | [GET_CMDID(IP_VS_SO_GET_VERSION)] = 64, |
| 2185 | [GET_CMDID(IP_VS_SO_GET_INFO)] = GET_INFO_ARG_LEN, | 2185 | [GET_CMDID(IP_VS_SO_GET_INFO)] = GET_INFO_ARG_LEN, |
| 2186 | [GET_CMDID(IP_VS_SO_GET_SERVICES)] = GET_SERVICES_ARG_LEN, | 2186 | [GET_CMDID(IP_VS_SO_GET_SERVICES)] = GET_SERVICES_ARG_LEN, |
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c index c19408973c09..0e878fd6215c 100644 --- a/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c | |||
| @@ -251,7 +251,7 @@ tcp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp) | |||
| 251 | #define TCP_DIR_OUTPUT 4 | 251 | #define TCP_DIR_OUTPUT 4 |
| 252 | #define TCP_DIR_INPUT_ONLY 8 | 252 | #define TCP_DIR_INPUT_ONLY 8 |
| 253 | 253 | ||
| 254 | static int tcp_state_off[IP_VS_DIR_LAST] = { | 254 | static const int tcp_state_off[IP_VS_DIR_LAST] = { |
| 255 | [IP_VS_DIR_INPUT] = TCP_DIR_INPUT, | 255 | [IP_VS_DIR_INPUT] = TCP_DIR_INPUT, |
| 256 | [IP_VS_DIR_OUTPUT] = TCP_DIR_OUTPUT, | 256 | [IP_VS_DIR_OUTPUT] = TCP_DIR_OUTPUT, |
| 257 | [IP_VS_DIR_INPUT_ONLY] = TCP_DIR_INPUT_ONLY, | 257 | [IP_VS_DIR_INPUT_ONLY] = TCP_DIR_INPUT_ONLY, |
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index fa3f914117ec..e52847fa10f5 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c | |||
| @@ -37,7 +37,7 @@ MODULE_LICENSE("GPL"); | |||
| 37 | module_param(master_timeout, int, 0600); | 37 | module_param(master_timeout, int, 0600); |
| 38 | MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); | 38 | MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); |
| 39 | 39 | ||
| 40 | static char *conns[] = { "DATA ", "MESG ", "INDEX " }; | 40 | static const char *conns[] = { "DATA ", "MESG ", "INDEX " }; |
| 41 | 41 | ||
| 42 | /* This is slow, but it's simple. --RR */ | 42 | /* This is slow, but it's simple. --RR */ |
| 43 | static char *amanda_buffer; | 43 | static char *amanda_buffer; |
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 422ab68ee7fb..7a4ecddd597b 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
| @@ -1354,7 +1354,7 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size) | |||
| 1354 | get_order(sizeof(struct list_head) * size)); | 1354 | get_order(sizeof(struct list_head) * size)); |
| 1355 | } | 1355 | } |
| 1356 | 1356 | ||
| 1357 | void ip_conntrack_flush() | 1357 | void ip_conntrack_flush(void) |
| 1358 | { | 1358 | { |
| 1359 | /* This makes sure all current packets have passed through | 1359 | /* This makes sure all current packets have passed through |
| 1360 | netfilter framework. Roll on, two-stage module | 1360 | netfilter framework. Roll on, two-stage module |
| @@ -1408,7 +1408,7 @@ static struct list_head *alloc_hashtable(int size, int *vmalloced) | |||
| 1408 | return hash; | 1408 | return hash; |
| 1409 | } | 1409 | } |
| 1410 | 1410 | ||
| 1411 | int set_hashsize(const char *val, struct kernel_param *kp) | 1411 | static int set_hashsize(const char *val, struct kernel_param *kp) |
| 1412 | { | 1412 | { |
| 1413 | int i, bucket, hashsize, vmalloced; | 1413 | int i, bucket, hashsize, vmalloced; |
| 1414 | int old_vmalloced, old_size; | 1414 | int old_vmalloced, old_size; |
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index 59e12b02b22c..68b173bcda60 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c | |||
| @@ -55,7 +55,7 @@ static int try_rfc959(const char *, size_t, u_int32_t [], char); | |||
| 55 | static int try_eprt(const char *, size_t, u_int32_t [], char); | 55 | static int try_eprt(const char *, size_t, u_int32_t [], char); |
| 56 | static int try_epsv_response(const char *, size_t, u_int32_t [], char); | 56 | static int try_epsv_response(const char *, size_t, u_int32_t [], char); |
| 57 | 57 | ||
| 58 | static struct ftp_search { | 58 | static const struct ftp_search { |
| 59 | enum ip_conntrack_dir dir; | 59 | enum ip_conntrack_dir dir; |
| 60 | const char *pattern; | 60 | const char *pattern; |
| 61 | size_t plen; | 61 | size_t plen; |
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index 2dea1db14406..d7c40421d0d1 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c | |||
| @@ -59,7 +59,7 @@ MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC | |||
| 59 | module_param(dcc_timeout, int, 0400); | 59 | module_param(dcc_timeout, int, 0400); |
| 60 | MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); | 60 | MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); |
| 61 | 61 | ||
| 62 | static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; | 62 | static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; |
| 63 | #define MINMATCHLEN 5 | 63 | #define MINMATCHLEN 5 |
| 64 | 64 | ||
| 65 | #if 0 | 65 | #if 0 |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c index e4d6b268e8c4..5f9925db608e 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c | |||
| @@ -51,7 +51,7 @@ static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple, | |||
| 51 | const struct ip_conntrack_tuple *orig) | 51 | const struct ip_conntrack_tuple *orig) |
| 52 | { | 52 | { |
| 53 | /* Add 1; spaces filled with 0. */ | 53 | /* Add 1; spaces filled with 0. */ |
| 54 | static u_int8_t invmap[] | 54 | static const u_int8_t invmap[] |
| 55 | = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1, | 55 | = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1, |
| 56 | [ICMP_ECHOREPLY] = ICMP_ECHO + 1, | 56 | [ICMP_ECHOREPLY] = ICMP_ECHO + 1, |
| 57 | [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, | 57 | [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, |
| @@ -110,7 +110,7 @@ static int icmp_packet(struct ip_conntrack *ct, | |||
| 110 | return NF_ACCEPT; | 110 | return NF_ACCEPT; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | static u_int8_t valid_new[] = { | 113 | static const u_int8_t valid_new[] = { |
| 114 | [ICMP_ECHO] = 1, | 114 | [ICMP_ECHO] = 1, |
| 115 | [ICMP_TIMESTAMP] = 1, | 115 | [ICMP_TIMESTAMP] = 1, |
| 116 | [ICMP_INFO_REQUEST] = 1, | 116 | [ICMP_INFO_REQUEST] = 1, |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index 59a4a0111dd3..977fb59d4563 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c | |||
| @@ -65,7 +65,7 @@ static unsigned long ip_ct_sctp_timeout_shutdown_sent = 300 SECS / 1000; | |||
| 65 | static unsigned long ip_ct_sctp_timeout_shutdown_recd = 300 SECS / 1000; | 65 | static unsigned long ip_ct_sctp_timeout_shutdown_recd = 300 SECS / 1000; |
| 66 | static unsigned long ip_ct_sctp_timeout_shutdown_ack_sent = 3 SECS; | 66 | static unsigned long ip_ct_sctp_timeout_shutdown_ack_sent = 3 SECS; |
| 67 | 67 | ||
| 68 | static unsigned long * sctp_timeouts[] | 68 | static const unsigned long * sctp_timeouts[] |
| 69 | = { NULL, /* SCTP_CONNTRACK_NONE */ | 69 | = { NULL, /* SCTP_CONNTRACK_NONE */ |
| 70 | &ip_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */ | 70 | &ip_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */ |
| 71 | &ip_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */ | 71 | &ip_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */ |
| @@ -118,7 +118,7 @@ cookie echoed to closed. | |||
| 118 | */ | 118 | */ |
| 119 | 119 | ||
| 120 | /* SCTP conntrack state transitions */ | 120 | /* SCTP conntrack state transitions */ |
| 121 | static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = { | 121 | static const enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = { |
| 122 | { | 122 | { |
| 123 | /* ORIGINAL */ | 123 | /* ORIGINAL */ |
| 124 | /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */ | 124 | /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index ee3b7d6c4d2e..aeb7353d4777 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
| @@ -99,7 +99,7 @@ unsigned long ip_ct_tcp_timeout_close = 10 SECS; | |||
| 99 | to ~13-30min depending on RTO. */ | 99 | to ~13-30min depending on RTO. */ |
| 100 | unsigned long ip_ct_tcp_timeout_max_retrans = 5 MINS; | 100 | unsigned long ip_ct_tcp_timeout_max_retrans = 5 MINS; |
| 101 | 101 | ||
| 102 | static unsigned long * tcp_timeouts[] | 102 | static const unsigned long * tcp_timeouts[] |
| 103 | = { NULL, /* TCP_CONNTRACK_NONE */ | 103 | = { NULL, /* TCP_CONNTRACK_NONE */ |
| 104 | &ip_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */ | 104 | &ip_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */ |
| 105 | &ip_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */ | 105 | &ip_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */ |
| @@ -170,7 +170,7 @@ enum tcp_bit_set { | |||
| 170 | * if they are invalid | 170 | * if they are invalid |
| 171 | * or we do not support the request (simultaneous open) | 171 | * or we do not support the request (simultaneous open) |
| 172 | */ | 172 | */ |
| 173 | static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { | 173 | static const enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { |
| 174 | { | 174 | { |
| 175 | /* ORIGINAL */ | 175 | /* ORIGINAL */ |
| 176 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ | 176 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ |
| @@ -272,9 +272,9 @@ static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { | |||
| 272 | * sCL -> sCL | 272 | * sCL -> sCL |
| 273 | */ | 273 | */ |
| 274 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ | 274 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ |
| 275 | /*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, | 275 | /*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, |
| 276 | /* | 276 | /* |
| 277 | * sSS -> sIV Might be a half-open connection. | 277 | * sSS -> sIG Might be a half-open connection. |
| 278 | * sSR -> sSR Might answer late resent SYN. | 278 | * sSR -> sSR Might answer late resent SYN. |
| 279 | * sES -> sES :-) | 279 | * sES -> sES :-) |
| 280 | * sFW -> sCW Normal close request answered by ACK. | 280 | * sFW -> sCW Normal close request answered by ACK. |
| @@ -817,7 +817,7 @@ void ip_conntrack_tcp_update(struct sk_buff *skb, | |||
| 817 | #define TH_CWR 0x80 | 817 | #define TH_CWR 0x80 |
| 818 | 818 | ||
| 819 | /* table of valid flag combinations - ECE and CWR are always valid */ | 819 | /* table of valid flag combinations - ECE and CWR are always valid */ |
| 820 | static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] = | 820 | static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] = |
| 821 | { | 821 | { |
| 822 | [TH_SYN] = 1, | 822 | [TH_SYN] = 1, |
| 823 | [TH_SYN|TH_ACK] = 1, | 823 | [TH_SYN|TH_ACK] = 1, |
| @@ -917,8 +917,12 @@ static int tcp_packet(struct ip_conntrack *conntrack, | |||
| 917 | 917 | ||
| 918 | switch (new_state) { | 918 | switch (new_state) { |
| 919 | case TCP_CONNTRACK_IGNORE: | 919 | case TCP_CONNTRACK_IGNORE: |
| 920 | /* Either SYN in ORIGINAL | 920 | /* Ignored packets: |
| 921 | * or SYN/ACK in REPLY. */ | 921 | * |
| 922 | * a) SYN in ORIGINAL | ||
| 923 | * b) SYN/ACK in REPLY | ||
| 924 | * c) ACK in reply direction after initial SYN in original. | ||
| 925 | */ | ||
| 922 | if (index == TCP_SYNACK_SET | 926 | if (index == TCP_SYNACK_SET |
| 923 | && conntrack->proto.tcp.last_index == TCP_SYN_SET | 927 | && conntrack->proto.tcp.last_index == TCP_SYN_SET |
| 924 | && conntrack->proto.tcp.last_dir != dir | 928 | && conntrack->proto.tcp.last_dir != dir |
| @@ -985,13 +989,20 @@ static int tcp_packet(struct ip_conntrack *conntrack, | |||
| 985 | } | 989 | } |
| 986 | case TCP_CONNTRACK_CLOSE: | 990 | case TCP_CONNTRACK_CLOSE: |
| 987 | if (index == TCP_RST_SET | 991 | if (index == TCP_RST_SET |
| 988 | && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) | 992 | && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) |
| 989 | && conntrack->proto.tcp.last_index == TCP_SYN_SET | 993 | && conntrack->proto.tcp.last_index == TCP_SYN_SET) |
| 994 | || (!test_bit(IPS_ASSURED_BIT, &conntrack->status) | ||
| 995 | && conntrack->proto.tcp.last_index == TCP_ACK_SET)) | ||
| 990 | && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { | 996 | && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { |
| 991 | /* RST sent to invalid SYN we had let trough | 997 | /* RST sent to invalid SYN or ACK we had let trough |
| 992 | * SYN was in window then, tear down connection. | 998 | * at a) and c) above: |
| 999 | * | ||
| 1000 | * a) SYN was in window then | ||
| 1001 | * c) we hold a half-open connection. | ||
| 1002 | * | ||
| 1003 | * Delete our connection entry. | ||
| 993 | * We skip window checking, because packet might ACK | 1004 | * We skip window checking, because packet might ACK |
| 994 | * segments we ignored in the SYN. */ | 1005 | * segments we ignored. */ |
| 995 | goto in_window; | 1006 | goto in_window; |
| 996 | } | 1007 | } |
| 997 | /* Just fall trough */ | 1008 | /* Just fall trough */ |
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index 762f4d93936b..c1a61462507f 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c | |||
| @@ -49,7 +49,7 @@ static unsigned int ip_nat_htable_size; | |||
| 49 | static struct list_head *bysource; | 49 | static struct list_head *bysource; |
| 50 | 50 | ||
| 51 | #define MAX_IP_NAT_PROTO 256 | 51 | #define MAX_IP_NAT_PROTO 256 |
| 52 | struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO]; | 52 | static struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO]; |
| 53 | 53 | ||
| 54 | static inline struct ip_nat_protocol * | 54 | static inline struct ip_nat_protocol * |
| 55 | __ip_nat_proto_find(u_int8_t protonum) | 55 | __ip_nat_proto_find(u_int8_t protonum) |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 75c27e92f6ab..45886c8475e8 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
| @@ -1892,7 +1892,7 @@ static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) | |||
| 1892 | return pos; | 1892 | return pos; |
| 1893 | } | 1893 | } |
| 1894 | 1894 | ||
| 1895 | static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = | 1895 | static const struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = |
| 1896 | { { "ip_tables_names", ipt_get_tables }, | 1896 | { { "ip_tables_names", ipt_get_tables }, |
| 1897 | { "ip_tables_targets", ipt_get_targets }, | 1897 | { "ip_tables_targets", ipt_get_targets }, |
| 1898 | { "ip_tables_matches", ipt_get_matches }, | 1898 | { "ip_tables_matches", ipt_get_matches }, |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 92ed050fac69..30be0f1dae37 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
| @@ -197,7 +197,7 @@ static void dump_packet(const struct nf_loginfo *info, | |||
| 197 | } | 197 | } |
| 198 | case IPPROTO_ICMP: { | 198 | case IPPROTO_ICMP: { |
| 199 | struct icmphdr _icmph, *ich; | 199 | struct icmphdr _icmph, *ich; |
| 200 | static size_t required_len[NR_ICMP_TYPES+1] | 200 | static const size_t required_len[NR_ICMP_TYPES+1] |
| 201 | = { [ICMP_ECHOREPLY] = 4, | 201 | = { [ICMP_ECHOREPLY] = 4, |
| 202 | [ICMP_DEST_UNREACH] | 202 | [ICMP_DEST_UNREACH] |
| 203 | = 8 + sizeof(struct iphdr), | 203 | = 8 + sizeof(struct iphdr), |
| @@ -351,7 +351,7 @@ static void dump_packet(const struct nf_loginfo *info, | |||
| 351 | /* maxlen = 230+ 91 + 230 + 252 = 803 */ | 351 | /* maxlen = 230+ 91 + 230 + 252 = 803 */ |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | struct nf_loginfo default_loginfo = { | 354 | static struct nf_loginfo default_loginfo = { |
| 355 | .type = NF_LOG_TYPE_LOG, | 355 | .type = NF_LOG_TYPE_LOG, |
| 356 | .u = { | 356 | .u = { |
| 357 | .log = { | 357 | .log = { |
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 2d44b07688af..261cbb4d4c49 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c | |||
| @@ -532,6 +532,7 @@ match(const struct sk_buff *skb, | |||
| 532 | } | 532 | } |
| 533 | if(info->seconds && info->hit_count) { | 533 | if(info->seconds && info->hit_count) { |
| 534 | for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) { | 534 | for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) { |
| 535 | if(r_list[location].last_pkts[pkt_count] == 0) break; | ||
| 535 | if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++; | 536 | if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++; |
| 536 | } | 537 | } |
| 537 | if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert; | 538 | if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert; |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index a65e508fbd40..0d7dc668db46 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
| @@ -98,7 +98,7 @@ fold_field(void *mib[], int offt) | |||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | /* snmp items */ | 100 | /* snmp items */ |
| 101 | static struct snmp_mib snmp4_ipstats_list[] = { | 101 | static const struct snmp_mib snmp4_ipstats_list[] = { |
| 102 | SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES), | 102 | SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES), |
| 103 | SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS), | 103 | SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS), |
| 104 | SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS), | 104 | SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS), |
| @@ -119,7 +119,7 @@ static struct snmp_mib snmp4_ipstats_list[] = { | |||
| 119 | SNMP_MIB_SENTINEL | 119 | SNMP_MIB_SENTINEL |
| 120 | }; | 120 | }; |
| 121 | 121 | ||
| 122 | static struct snmp_mib snmp4_icmp_list[] = { | 122 | static const struct snmp_mib snmp4_icmp_list[] = { |
| 123 | SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), | 123 | SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), |
| 124 | SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), | 124 | SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), |
| 125 | SNMP_MIB_ITEM("InDestUnreachs", ICMP_MIB_INDESTUNREACHS), | 125 | SNMP_MIB_ITEM("InDestUnreachs", ICMP_MIB_INDESTUNREACHS), |
| @@ -149,7 +149,7 @@ static struct snmp_mib snmp4_icmp_list[] = { | |||
| 149 | SNMP_MIB_SENTINEL | 149 | SNMP_MIB_SENTINEL |
| 150 | }; | 150 | }; |
| 151 | 151 | ||
| 152 | static struct snmp_mib snmp4_tcp_list[] = { | 152 | static const struct snmp_mib snmp4_tcp_list[] = { |
| 153 | SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM), | 153 | SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM), |
| 154 | SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN), | 154 | SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN), |
| 155 | SNMP_MIB_ITEM("RtoMax", TCP_MIB_RTOMAX), | 155 | SNMP_MIB_ITEM("RtoMax", TCP_MIB_RTOMAX), |
| @@ -167,7 +167,7 @@ static struct snmp_mib snmp4_tcp_list[] = { | |||
| 167 | SNMP_MIB_SENTINEL | 167 | SNMP_MIB_SENTINEL |
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | static struct snmp_mib snmp4_udp_list[] = { | 170 | static const struct snmp_mib snmp4_udp_list[] = { |
| 171 | SNMP_MIB_ITEM("InDatagrams", UDP_MIB_INDATAGRAMS), | 171 | SNMP_MIB_ITEM("InDatagrams", UDP_MIB_INDATAGRAMS), |
| 172 | SNMP_MIB_ITEM("NoPorts", UDP_MIB_NOPORTS), | 172 | SNMP_MIB_ITEM("NoPorts", UDP_MIB_NOPORTS), |
| 173 | SNMP_MIB_ITEM("InErrors", UDP_MIB_INERRORS), | 173 | SNMP_MIB_ITEM("InErrors", UDP_MIB_INERRORS), |
| @@ -175,7 +175,7 @@ static struct snmp_mib snmp4_udp_list[] = { | |||
| 175 | SNMP_MIB_SENTINEL | 175 | SNMP_MIB_SENTINEL |
| 176 | }; | 176 | }; |
| 177 | 177 | ||
| 178 | static struct snmp_mib snmp4_net_list[] = { | 178 | static const struct snmp_mib snmp4_net_list[] = { |
| 179 | SNMP_MIB_ITEM("SyncookiesSent", LINUX_MIB_SYNCOOKIESSENT), | 179 | SNMP_MIB_ITEM("SyncookiesSent", LINUX_MIB_SYNCOOKIESSENT), |
| 180 | SNMP_MIB_ITEM("SyncookiesRecv", LINUX_MIB_SYNCOOKIESRECV), | 180 | SNMP_MIB_ITEM("SyncookiesRecv", LINUX_MIB_SYNCOOKIESRECV), |
| 181 | SNMP_MIB_ITEM("SyncookiesFailed", LINUX_MIB_SYNCOOKIESFAILED), | 181 | SNMP_MIB_ITEM("SyncookiesFailed", LINUX_MIB_SYNCOOKIESFAILED), |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 381dd6a6aebb..f701a136a6ae 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1371,7 +1371,7 @@ out: kfree_skb(skb); | |||
| 1371 | * are needed for AMPRnet AX.25 paths. | 1371 | * are needed for AMPRnet AX.25 paths. |
| 1372 | */ | 1372 | */ |
| 1373 | 1373 | ||
| 1374 | static unsigned short mtu_plateau[] = | 1374 | static const unsigned short mtu_plateau[] = |
| 1375 | {32000, 17914, 8166, 4352, 2002, 1492, 576, 296, 216, 128 }; | 1375 | {32000, 17914, 8166, 4352, 2002, 1492, 576, 296, 216, 128 }; |
| 1376 | 1376 | ||
| 1377 | static __inline__ unsigned short guess_mtu(unsigned short old_mtu) | 1377 | static __inline__ unsigned short guess_mtu(unsigned short old_mtu) |
| @@ -3149,8 +3149,7 @@ int __init ip_rt_init(void) | |||
| 3149 | sizeof(struct rt_hash_bucket), | 3149 | sizeof(struct rt_hash_bucket), |
| 3150 | rhash_entries, | 3150 | rhash_entries, |
| 3151 | (num_physpages >= 128 * 1024) ? | 3151 | (num_physpages >= 128 * 1024) ? |
| 3152 | (27 - PAGE_SHIFT) : | 3152 | 15 : 17, |
| 3153 | (29 - PAGE_SHIFT), | ||
| 3154 | HASH_HIGHMEM, | 3153 | HASH_HIGHMEM, |
| 3155 | &rt_hash_log, | 3154 | &rt_hash_log, |
| 3156 | &rt_hash_mask, | 3155 | &rt_hash_mask, |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9ac7a4f46bd8..ef98b14ac56d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1413,7 +1413,7 @@ recv_urg: | |||
| 1413 | * closed. | 1413 | * closed. |
| 1414 | */ | 1414 | */ |
| 1415 | 1415 | ||
| 1416 | static unsigned char new_state[16] = { | 1416 | static const unsigned char new_state[16] = { |
| 1417 | /* current state: new state: action: */ | 1417 | /* current state: new state: action: */ |
| 1418 | /* (Invalid) */ TCP_CLOSE, | 1418 | /* (Invalid) */ TCP_CLOSE, |
| 1419 | /* TCP_ESTABLISHED */ TCP_FIN_WAIT1 | TCP_ACTION_FIN, | 1419 | /* TCP_ESTABLISHED */ TCP_FIN_WAIT1 | TCP_ACTION_FIN, |
| @@ -2065,8 +2065,7 @@ void __init tcp_init(void) | |||
| 2065 | sizeof(struct inet_ehash_bucket), | 2065 | sizeof(struct inet_ehash_bucket), |
| 2066 | thash_entries, | 2066 | thash_entries, |
| 2067 | (num_physpages >= 128 * 1024) ? | 2067 | (num_physpages >= 128 * 1024) ? |
| 2068 | (25 - PAGE_SHIFT) : | 2068 | 13 : 15, |
| 2069 | (27 - PAGE_SHIFT), | ||
| 2070 | HASH_HIGHMEM, | 2069 | HASH_HIGHMEM, |
| 2071 | &tcp_hashinfo.ehash_size, | 2070 | &tcp_hashinfo.ehash_size, |
| 2072 | NULL, | 2071 | NULL, |
| @@ -2082,8 +2081,7 @@ void __init tcp_init(void) | |||
| 2082 | sizeof(struct inet_bind_hashbucket), | 2081 | sizeof(struct inet_bind_hashbucket), |
| 2083 | tcp_hashinfo.ehash_size, | 2082 | tcp_hashinfo.ehash_size, |
| 2084 | (num_physpages >= 128 * 1024) ? | 2083 | (num_physpages >= 128 * 1024) ? |
| 2085 | (25 - PAGE_SHIFT) : | 2084 | 13 : 15, |
| 2086 | (27 - PAGE_SHIFT), | ||
| 2087 | HASH_HIGHMEM, | 2085 | HASH_HIGHMEM, |
| 2088 | &tcp_hashinfo.bhash_size, | 2086 | &tcp_hashinfo.bhash_size, |
| 2089 | NULL, | 2087 | NULL, |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index c63b8ce0e1b5..d9546380fa04 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -92,10 +92,13 @@ static int inet6_create(struct socket *sock, int protocol) | |||
| 92 | struct proto *answer_prot; | 92 | struct proto *answer_prot; |
| 93 | unsigned char answer_flags; | 93 | unsigned char answer_flags; |
| 94 | char answer_no_check; | 94 | char answer_no_check; |
| 95 | int rc; | 95 | int try_loading_module = 0; |
| 96 | int err; | ||
| 96 | 97 | ||
| 97 | /* Look for the requested type/protocol pair. */ | 98 | /* Look for the requested type/protocol pair. */ |
| 98 | answer = NULL; | 99 | answer = NULL; |
| 100 | lookup_protocol: | ||
| 101 | err = -ESOCKTNOSUPPORT; | ||
| 99 | rcu_read_lock(); | 102 | rcu_read_lock(); |
| 100 | list_for_each_rcu(p, &inetsw6[sock->type]) { | 103 | list_for_each_rcu(p, &inetsw6[sock->type]) { |
| 101 | answer = list_entry(p, struct inet_protosw, list); | 104 | answer = list_entry(p, struct inet_protosw, list); |
| @@ -113,21 +116,37 @@ static int inet6_create(struct socket *sock, int protocol) | |||
| 113 | if (IPPROTO_IP == answer->protocol) | 116 | if (IPPROTO_IP == answer->protocol) |
| 114 | break; | 117 | break; |
| 115 | } | 118 | } |
| 119 | err = -EPROTONOSUPPORT; | ||
| 116 | answer = NULL; | 120 | answer = NULL; |
| 117 | } | 121 | } |
| 118 | 122 | ||
| 119 | rc = -ESOCKTNOSUPPORT; | 123 | if (!answer) { |
| 120 | if (!answer) | 124 | if (try_loading_module < 2) { |
| 121 | goto out_rcu_unlock; | 125 | rcu_read_unlock(); |
| 122 | rc = -EPERM; | 126 | /* |
| 127 | * Be more specific, e.g. net-pf-10-proto-132-type-1 | ||
| 128 | * (net-pf-PF_INET6-proto-IPPROTO_SCTP-type-SOCK_STREAM) | ||
| 129 | */ | ||
| 130 | if (++try_loading_module == 1) | ||
| 131 | request_module("net-pf-%d-proto-%d-type-%d", | ||
| 132 | PF_INET6, protocol, sock->type); | ||
| 133 | /* | ||
| 134 | * Fall back to generic, e.g. net-pf-10-proto-132 | ||
| 135 | * (net-pf-PF_INET6-proto-IPPROTO_SCTP) | ||
| 136 | */ | ||
| 137 | else | ||
| 138 | request_module("net-pf-%d-proto-%d", | ||
| 139 | PF_INET6, protocol); | ||
| 140 | goto lookup_protocol; | ||
| 141 | } else | ||
| 142 | goto out_rcu_unlock; | ||
| 143 | } | ||
| 144 | |||
| 145 | err = -EPERM; | ||
| 123 | if (answer->capability > 0 && !capable(answer->capability)) | 146 | if (answer->capability > 0 && !capable(answer->capability)) |
| 124 | goto out_rcu_unlock; | 147 | goto out_rcu_unlock; |
| 125 | rc = -EPROTONOSUPPORT; | ||
| 126 | if (!protocol) | ||
| 127 | goto out_rcu_unlock; | ||
| 128 | 148 | ||
| 129 | sock->ops = answer->ops; | 149 | sock->ops = answer->ops; |
| 130 | |||
| 131 | answer_prot = answer->prot; | 150 | answer_prot = answer->prot; |
| 132 | answer_no_check = answer->no_check; | 151 | answer_no_check = answer->no_check; |
| 133 | answer_flags = answer->flags; | 152 | answer_flags = answer->flags; |
| @@ -135,14 +154,14 @@ static int inet6_create(struct socket *sock, int protocol) | |||
| 135 | 154 | ||
| 136 | BUG_TRAP(answer_prot->slab != NULL); | 155 | BUG_TRAP(answer_prot->slab != NULL); |
| 137 | 156 | ||
| 138 | rc = -ENOBUFS; | 157 | err = -ENOBUFS; |
| 139 | sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1); | 158 | sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1); |
| 140 | if (sk == NULL) | 159 | if (sk == NULL) |
| 141 | goto out; | 160 | goto out; |
| 142 | 161 | ||
| 143 | sock_init_data(sock, sk); | 162 | sock_init_data(sock, sk); |
| 144 | 163 | ||
| 145 | rc = 0; | 164 | err = 0; |
| 146 | sk->sk_no_check = answer_no_check; | 165 | sk->sk_no_check = answer_no_check; |
| 147 | if (INET_PROTOSW_REUSE & answer_flags) | 166 | if (INET_PROTOSW_REUSE & answer_flags) |
| 148 | sk->sk_reuse = 1; | 167 | sk->sk_reuse = 1; |
| @@ -202,14 +221,14 @@ static int inet6_create(struct socket *sock, int protocol) | |||
| 202 | sk->sk_prot->hash(sk); | 221 | sk->sk_prot->hash(sk); |
| 203 | } | 222 | } |
| 204 | if (sk->sk_prot->init) { | 223 | if (sk->sk_prot->init) { |
| 205 | rc = sk->sk_prot->init(sk); | 224 | err = sk->sk_prot->init(sk); |
| 206 | if (rc) { | 225 | if (err) { |
| 207 | sk_common_release(sk); | 226 | sk_common_release(sk); |
| 208 | goto out; | 227 | goto out; |
| 209 | } | 228 | } |
| 210 | } | 229 | } |
| 211 | out: | 230 | out: |
| 212 | return rc; | 231 | return err; |
| 213 | out_rcu_unlock: | 232 | out_rcu_unlock: |
| 214 | rcu_read_unlock(); | 233 | rcu_read_unlock(); |
| 215 | goto out; | 234 | goto out; |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 1bdf0fb8bf8a..34a332225c17 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
| @@ -751,7 +751,7 @@ void icmpv6_cleanup(void) | |||
| 751 | inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); | 751 | inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); |
| 752 | } | 752 | } |
| 753 | 753 | ||
| 754 | static struct icmp6_err { | 754 | static const struct icmp6_err { |
| 755 | int err; | 755 | int err; |
| 756 | int fatal; | 756 | int fatal; |
| 757 | } tab_unreach[] = { | 757 | } tab_unreach[] = { |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index c1fa693511a1..8523c76ebf76 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -774,7 +774,8 @@ out_err_release: | |||
| 774 | *dst = NULL; | 774 | *dst = NULL; |
| 775 | return err; | 775 | return err; |
| 776 | } | 776 | } |
| 777 | inline int ip6_ufo_append_data(struct sock *sk, | 777 | |
| 778 | static inline int ip6_ufo_append_data(struct sock *sk, | ||
| 778 | int getfrag(void *from, char *to, int offset, int len, | 779 | int getfrag(void *from, char *to, int offset, int len, |
| 779 | int odd, struct sk_buff *skb), | 780 | int odd, struct sk_buff *skb), |
| 780 | void *from, int length, int hh_len, int fragheaderlen, | 781 | void *from, int length, int hh_len, int fragheaderlen, |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 25757ade989f..3620718defe6 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
| @@ -628,8 +628,8 @@ e_inval: | |||
| 628 | return -EINVAL; | 628 | return -EINVAL; |
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr, | 631 | static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr, |
| 632 | char __user *optval, int len) | 632 | char __user *optval, int len) |
| 633 | { | 633 | { |
| 634 | if (!hdr) | 634 | if (!hdr) |
| 635 | return 0; | 635 | return 0; |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index f15e04ad026e..fd939da090c4 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
| @@ -1231,6 +1231,11 @@ int igmp6_event_report(struct sk_buff *skb) | |||
| 1231 | if (skb->pkt_type == PACKET_LOOPBACK) | 1231 | if (skb->pkt_type == PACKET_LOOPBACK) |
| 1232 | return 0; | 1232 | return 0; |
| 1233 | 1233 | ||
| 1234 | /* send our report if the MC router may not have heard this report */ | ||
| 1235 | if (skb->pkt_type != PACKET_MULTICAST && | ||
| 1236 | skb->pkt_type != PACKET_BROADCAST) | ||
| 1237 | return 0; | ||
| 1238 | |||
| 1234 | if (!pskb_may_pull(skb, sizeof(struct in6_addr))) | 1239 | if (!pskb_may_pull(skb, sizeof(struct in6_addr))) |
| 1235 | return -EINVAL; | 1240 | return -EINVAL; |
| 1236 | 1241 | ||
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 7d492226c16e..95d469271c4d 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
| @@ -1972,7 +1972,7 @@ static int ip6t_get_matches(char *buffer, char **start, off_t offset, int length | |||
| 1972 | return pos; | 1972 | return pos; |
| 1973 | } | 1973 | } |
| 1974 | 1974 | ||
| 1975 | static struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] = | 1975 | static const struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] = |
| 1976 | { { "ip6_tables_names", ip6t_get_tables }, | 1976 | { { "ip6_tables_names", ip6t_get_tables }, |
| 1977 | { "ip6_tables_targets", ip6t_get_targets }, | 1977 | { "ip6_tables_targets", ip6t_get_targets }, |
| 1978 | { "ip6_tables_matches", ip6t_get_matches }, | 1978 | { "ip6_tables_matches", ip6t_get_matches }, |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 5a6fcf349bdf..6035633d8225 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
| @@ -280,9 +280,9 @@ static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { | |||
| 280 | * sCL -> sCL | 280 | * sCL -> sCL |
| 281 | */ | 281 | */ |
| 282 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ | 282 | /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ |
| 283 | /*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, | 283 | /*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, |
| 284 | /* | 284 | /* |
| 285 | * sSS -> sIV Might be a half-open connection. | 285 | * sSS -> sIG Might be a half-open connection. |
| 286 | * sSR -> sSR Might answer late resent SYN. | 286 | * sSR -> sSR Might answer late resent SYN. |
| 287 | * sES -> sES :-) | 287 | * sES -> sES :-) |
| 288 | * sFW -> sCW Normal close request answered by ACK. | 288 | * sFW -> sCW Normal close request answered by ACK. |
| @@ -912,8 +912,12 @@ static int tcp_packet(struct nf_conn *conntrack, | |||
| 912 | 912 | ||
| 913 | switch (new_state) { | 913 | switch (new_state) { |
| 914 | case TCP_CONNTRACK_IGNORE: | 914 | case TCP_CONNTRACK_IGNORE: |
| 915 | /* Either SYN in ORIGINAL | 915 | /* Ignored packets: |
| 916 | * or SYN/ACK in REPLY. */ | 916 | * |
| 917 | * a) SYN in ORIGINAL | ||
| 918 | * b) SYN/ACK in REPLY | ||
| 919 | * c) ACK in reply direction after initial SYN in original. | ||
| 920 | */ | ||
| 917 | if (index == TCP_SYNACK_SET | 921 | if (index == TCP_SYNACK_SET |
| 918 | && conntrack->proto.tcp.last_index == TCP_SYN_SET | 922 | && conntrack->proto.tcp.last_index == TCP_SYN_SET |
| 919 | && conntrack->proto.tcp.last_dir != dir | 923 | && conntrack->proto.tcp.last_dir != dir |
| @@ -979,13 +983,20 @@ static int tcp_packet(struct nf_conn *conntrack, | |||
| 979 | } | 983 | } |
| 980 | case TCP_CONNTRACK_CLOSE: | 984 | case TCP_CONNTRACK_CLOSE: |
| 981 | if (index == TCP_RST_SET | 985 | if (index == TCP_RST_SET |
| 982 | && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) | 986 | && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) |
| 983 | && conntrack->proto.tcp.last_index == TCP_SYN_SET | 987 | && conntrack->proto.tcp.last_index == TCP_SYN_SET) |
| 988 | || (!test_bit(IPS_ASSURED_BIT, &conntrack->status) | ||
| 989 | && conntrack->proto.tcp.last_index == TCP_ACK_SET)) | ||
| 984 | && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { | 990 | && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { |
| 985 | /* RST sent to invalid SYN we had let trough | 991 | /* RST sent to invalid SYN or ACK we had let trough |
| 986 | * SYN was in window then, tear down connection. | 992 | * at a) and c) above: |
| 993 | * | ||
| 994 | * a) SYN was in window then | ||
| 995 | * c) we hold a half-open connection. | ||
| 996 | * | ||
| 997 | * Delete our connection entry. | ||
| 987 | * We skip window checking, because packet might ACK | 998 | * We skip window checking, because packet might ACK |
| 988 | * segments we ignored in the SYN. */ | 999 | * segments we ignored. */ |
| 989 | goto in_window; | 1000 | goto in_window; |
| 990 | } | 1001 | } |
| 991 | /* Just fall trough */ | 1002 | /* Just fall trough */ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index abab81f3818f..d890dfa8818f 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -4743,11 +4743,6 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, | |||
| 4743 | struct sk_buff *skb; | 4743 | struct sk_buff *skb; |
| 4744 | long timeo; | 4744 | long timeo; |
| 4745 | 4745 | ||
| 4746 | /* Caller is allowed not to check sk->sk_err before calling. */ | ||
| 4747 | error = sock_error(sk); | ||
| 4748 | if (error) | ||
| 4749 | goto no_packet; | ||
| 4750 | |||
| 4751 | timeo = sock_rcvtimeo(sk, noblock); | 4746 | timeo = sock_rcvtimeo(sk, noblock); |
| 4752 | 4747 | ||
| 4753 | SCTP_DEBUG_PRINTK("Timeout: timeo: %ld, MAX: %ld.\n", | 4748 | SCTP_DEBUG_PRINTK("Timeout: timeo: %ld, MAX: %ld.\n", |
| @@ -4774,6 +4769,11 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags, | |||
| 4774 | if (skb) | 4769 | if (skb) |
| 4775 | return skb; | 4770 | return skb; |
| 4776 | 4771 | ||
| 4772 | /* Caller is allowed not to check sk->sk_err before calling. */ | ||
| 4773 | error = sock_error(sk); | ||
| 4774 | if (error) | ||
| 4775 | goto no_packet; | ||
| 4776 | |||
| 4777 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 4777 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
| 4778 | break; | 4778 | break; |
| 4779 | 4779 | ||
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 6bc27200e6ca..268ddaf2dc0f 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
| @@ -261,7 +261,8 @@ void sctp_transport_route(struct sctp_transport *transport, | |||
| 261 | * association's active path for getsockname(). | 261 | * association's active path for getsockname(). |
| 262 | */ | 262 | */ |
| 263 | if (asoc && (transport == asoc->peer.active_path)) | 263 | if (asoc && (transport == asoc->peer.active_path)) |
| 264 | af->to_sk_saddr(&transport->saddr, asoc->base.sk); | 264 | opt->pf->af->to_sk_saddr(&transport->saddr, |
| 265 | asoc->base.sk); | ||
| 265 | } else | 266 | } else |
| 266 | transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; | 267 | transport->pmtu = SCTP_DEFAULT_MAXSEGMENT; |
| 267 | } | 268 | } |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index e3b242daf53c..c76ea221798c 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -59,7 +59,6 @@ __rpc_purge_upcall(struct inode *inode, int err) | |||
| 59 | struct rpc_inode *rpci = RPC_I(inode); | 59 | struct rpc_inode *rpci = RPC_I(inode); |
| 60 | 60 | ||
| 61 | __rpc_purge_list(rpci, &rpci->pipe, err); | 61 | __rpc_purge_list(rpci, &rpci->pipe, err); |
| 62 | __rpc_purge_list(rpci, &rpci->in_upcall, err); | ||
| 63 | rpci->pipelen = 0; | 62 | rpci->pipelen = 0; |
| 64 | wake_up(&rpci->waitq); | 63 | wake_up(&rpci->waitq); |
| 65 | } | 64 | } |
| @@ -119,6 +118,7 @@ rpc_close_pipes(struct inode *inode) | |||
| 119 | down(&inode->i_sem); | 118 | down(&inode->i_sem); |
| 120 | if (rpci->ops != NULL) { | 119 | if (rpci->ops != NULL) { |
| 121 | rpci->nreaders = 0; | 120 | rpci->nreaders = 0; |
| 121 | __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE); | ||
| 122 | __rpc_purge_upcall(inode, -EPIPE); | 122 | __rpc_purge_upcall(inode, -EPIPE); |
| 123 | rpci->nwriters = 0; | 123 | rpci->nwriters = 0; |
| 124 | if (rpci->ops->release_pipe) | 124 | if (rpci->ops->release_pipe) |
