diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/Makefile | 3 | ||||
-rw-r--r-- | net/core/dev.c | 142 | ||||
-rw-r--r-- | net/core/dst.c | 15 | ||||
-rw-r--r-- | net/core/filter.c | 104 | ||||
-rw-r--r-- | net/core/neighbour.c | 9 | ||||
-rw-r--r-- | net/core/netpoll.c | 133 | ||||
-rw-r--r-- | net/core/pktgen.c | 31 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 2 | ||||
-rw-r--r-- | net/core/skbuff.c | 180 | ||||
-rw-r--r-- | net/core/sock.c | 24 | ||||
-rw-r--r-- | net/core/sysctl_net_core.c | 61 | ||||
-rw-r--r-- | net/core/utils.c | 37 | ||||
-rw-r--r-- | net/core/wireless.c | 1 |
13 files changed, 407 insertions, 335 deletions
diff --git a/net/core/Makefile b/net/core/Makefile index 5e0c56b7f6..f5f5e58943 100644 --- a/net/core/Makefile +++ b/net/core/Makefile | |||
@@ -7,9 +7,10 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ | |||
7 | 7 | ||
8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o | 8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o |
9 | 9 | ||
10 | obj-y += flow.o dev.o ethtool.o dev_mcast.o dst.o \ | 10 | obj-y += dev.o ethtool.o dev_mcast.o dst.o \ |
11 | neighbour.o rtnetlink.o utils.o link_watch.o filter.o | 11 | neighbour.o rtnetlink.o utils.o link_watch.o filter.o |
12 | 12 | ||
13 | obj-$(CONFIG_XFRM) += flow.o | ||
13 | obj-$(CONFIG_SYSFS) += net-sysfs.o | 14 | obj-$(CONFIG_SYSFS) += net-sysfs.o |
14 | obj-$(CONFIG_NETFILTER) += netfilter.o | 15 | obj-$(CONFIG_NETFILTER) += netfilter.o |
15 | obj-$(CONFIG_NET_DIVERT) += dv.o | 16 | obj-$(CONFIG_NET_DIVERT) += dv.o |
diff --git a/net/core/dev.c b/net/core/dev.c index ab935778ce..faf59b02c4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -115,18 +115,6 @@ | |||
115 | #endif /* CONFIG_NET_RADIO */ | 115 | #endif /* CONFIG_NET_RADIO */ |
116 | #include <asm/current.h> | 116 | #include <asm/current.h> |
117 | 117 | ||
118 | /* This define, if set, will randomly drop a packet when congestion | ||
119 | * is more than moderate. It helps fairness in the multi-interface | ||
120 | * case when one of them is a hog, but it kills performance for the | ||
121 | * single interface case so it is off now by default. | ||
122 | */ | ||
123 | #undef RAND_LIE | ||
124 | |||
125 | /* Setting this will sample the queue lengths and thus congestion | ||
126 | * via a timer instead of as each packet is received. | ||
127 | */ | ||
128 | #undef OFFLINE_SAMPLE | ||
129 | |||
130 | /* | 118 | /* |
131 | * The list of packet types we will receive (as opposed to discard) | 119 | * The list of packet types we will receive (as opposed to discard) |
132 | * and the routines to invoke. | 120 | * and the routines to invoke. |
@@ -159,11 +147,6 @@ static DEFINE_SPINLOCK(ptype_lock); | |||
159 | static struct list_head ptype_base[16]; /* 16 way hashed list */ | 147 | static struct list_head ptype_base[16]; /* 16 way hashed list */ |
160 | static struct list_head ptype_all; /* Taps */ | 148 | static struct list_head ptype_all; /* Taps */ |
161 | 149 | ||
162 | #ifdef OFFLINE_SAMPLE | ||
163 | static void sample_queue(unsigned long dummy); | ||
164 | static struct timer_list samp_timer = TIMER_INITIALIZER(sample_queue, 0, 0); | ||
165 | #endif | ||
166 | |||
167 | /* | 150 | /* |
168 | * The @dev_base list is protected by @dev_base_lock and the rtln | 151 | * The @dev_base list is protected by @dev_base_lock and the rtln |
169 | * semaphore. | 152 | * semaphore. |
@@ -215,7 +198,7 @@ static struct notifier_block *netdev_chain; | |||
215 | * Device drivers call our routines to queue packets here. We empty the | 198 | * Device drivers call our routines to queue packets here. We empty the |
216 | * queue in the local softnet handler. | 199 | * queue in the local softnet handler. |
217 | */ | 200 | */ |
218 | DEFINE_PER_CPU(struct softnet_data, softnet_data) = { 0, }; | 201 | DEFINE_PER_CPU(struct softnet_data, softnet_data) = { NULL }; |
219 | 202 | ||
220 | #ifdef CONFIG_SYSFS | 203 | #ifdef CONFIG_SYSFS |
221 | extern int netdev_sysfs_init(void); | 204 | extern int netdev_sysfs_init(void); |
@@ -918,8 +901,7 @@ int dev_close(struct net_device *dev) | |||
918 | smp_mb__after_clear_bit(); /* Commit netif_running(). */ | 901 | smp_mb__after_clear_bit(); /* Commit netif_running(). */ |
919 | while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) { | 902 | while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) { |
920 | /* No hurry. */ | 903 | /* No hurry. */ |
921 | current->state = TASK_INTERRUPTIBLE; | 904 | msleep(1); |
922 | schedule_timeout(1); | ||
923 | } | 905 | } |
924 | 906 | ||
925 | /* | 907 | /* |
@@ -1144,7 +1126,7 @@ static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb) | |||
1144 | extern void skb_release_data(struct sk_buff *); | 1126 | extern void skb_release_data(struct sk_buff *); |
1145 | 1127 | ||
1146 | /* Keep head the same: replace data */ | 1128 | /* Keep head the same: replace data */ |
1147 | int __skb_linearize(struct sk_buff *skb, int gfp_mask) | 1129 | int __skb_linearize(struct sk_buff *skb, unsigned int __nocast gfp_mask) |
1148 | { | 1130 | { |
1149 | unsigned int size; | 1131 | unsigned int size; |
1150 | u8 *data; | 1132 | u8 *data; |
@@ -1363,71 +1345,13 @@ out: | |||
1363 | Receiver routines | 1345 | Receiver routines |
1364 | =======================================================================*/ | 1346 | =======================================================================*/ |
1365 | 1347 | ||
1366 | int netdev_max_backlog = 300; | 1348 | int netdev_max_backlog = 1000; |
1349 | int netdev_budget = 300; | ||
1367 | int weight_p = 64; /* old backlog weight */ | 1350 | int weight_p = 64; /* old backlog weight */ |
1368 | /* These numbers are selected based on intuition and some | ||
1369 | * experimentatiom, if you have more scientific way of doing this | ||
1370 | * please go ahead and fix things. | ||
1371 | */ | ||
1372 | int no_cong_thresh = 10; | ||
1373 | int no_cong = 20; | ||
1374 | int lo_cong = 100; | ||
1375 | int mod_cong = 290; | ||
1376 | 1351 | ||
1377 | DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; | 1352 | DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, }; |
1378 | 1353 | ||
1379 | 1354 | ||
1380 | static void get_sample_stats(int cpu) | ||
1381 | { | ||
1382 | #ifdef RAND_LIE | ||
1383 | unsigned long rd; | ||
1384 | int rq; | ||
1385 | #endif | ||
1386 | struct softnet_data *sd = &per_cpu(softnet_data, cpu); | ||
1387 | int blog = sd->input_pkt_queue.qlen; | ||
1388 | int avg_blog = sd->avg_blog; | ||
1389 | |||
1390 | avg_blog = (avg_blog >> 1) + (blog >> 1); | ||
1391 | |||
1392 | if (avg_blog > mod_cong) { | ||
1393 | /* Above moderate congestion levels. */ | ||
1394 | sd->cng_level = NET_RX_CN_HIGH; | ||
1395 | #ifdef RAND_LIE | ||
1396 | rd = net_random(); | ||
1397 | rq = rd % netdev_max_backlog; | ||
1398 | if (rq < avg_blog) /* unlucky bastard */ | ||
1399 | sd->cng_level = NET_RX_DROP; | ||
1400 | #endif | ||
1401 | } else if (avg_blog > lo_cong) { | ||
1402 | sd->cng_level = NET_RX_CN_MOD; | ||
1403 | #ifdef RAND_LIE | ||
1404 | rd = net_random(); | ||
1405 | rq = rd % netdev_max_backlog; | ||
1406 | if (rq < avg_blog) /* unlucky bastard */ | ||
1407 | sd->cng_level = NET_RX_CN_HIGH; | ||
1408 | #endif | ||
1409 | } else if (avg_blog > no_cong) | ||
1410 | sd->cng_level = NET_RX_CN_LOW; | ||
1411 | else /* no congestion */ | ||
1412 | sd->cng_level = NET_RX_SUCCESS; | ||
1413 | |||
1414 | sd->avg_blog = avg_blog; | ||
1415 | } | ||
1416 | |||
1417 | #ifdef OFFLINE_SAMPLE | ||
1418 | static void sample_queue(unsigned long dummy) | ||
1419 | { | ||
1420 | /* 10 ms 0r 1ms -- i don't care -- JHS */ | ||
1421 | int next_tick = 1; | ||
1422 | int cpu = smp_processor_id(); | ||
1423 | |||
1424 | get_sample_stats(cpu); | ||
1425 | next_tick += jiffies; | ||
1426 | mod_timer(&samp_timer, next_tick); | ||
1427 | } | ||
1428 | #endif | ||
1429 | |||
1430 | |||
1431 | /** | 1355 | /** |
1432 | * netif_rx - post buffer to the network code | 1356 | * netif_rx - post buffer to the network code |
1433 | * @skb: buffer to post | 1357 | * @skb: buffer to post |
@@ -1448,7 +1372,6 @@ static void sample_queue(unsigned long dummy) | |||
1448 | 1372 | ||
1449 | int netif_rx(struct sk_buff *skb) | 1373 | int netif_rx(struct sk_buff *skb) |
1450 | { | 1374 | { |
1451 | int this_cpu; | ||
1452 | struct softnet_data *queue; | 1375 | struct softnet_data *queue; |
1453 | unsigned long flags; | 1376 | unsigned long flags; |
1454 | 1377 | ||
@@ -1464,38 +1387,22 @@ int netif_rx(struct sk_buff *skb) | |||
1464 | * short when CPU is congested, but is still operating. | 1387 | * short when CPU is congested, but is still operating. |
1465 | */ | 1388 | */ |
1466 | local_irq_save(flags); | 1389 | local_irq_save(flags); |
1467 | this_cpu = smp_processor_id(); | ||
1468 | queue = &__get_cpu_var(softnet_data); | 1390 | queue = &__get_cpu_var(softnet_data); |
1469 | 1391 | ||
1470 | __get_cpu_var(netdev_rx_stat).total++; | 1392 | __get_cpu_var(netdev_rx_stat).total++; |
1471 | if (queue->input_pkt_queue.qlen <= netdev_max_backlog) { | 1393 | if (queue->input_pkt_queue.qlen <= netdev_max_backlog) { |
1472 | if (queue->input_pkt_queue.qlen) { | 1394 | if (queue->input_pkt_queue.qlen) { |
1473 | if (queue->throttle) | ||
1474 | goto drop; | ||
1475 | |||
1476 | enqueue: | 1395 | enqueue: |
1477 | dev_hold(skb->dev); | 1396 | dev_hold(skb->dev); |
1478 | __skb_queue_tail(&queue->input_pkt_queue, skb); | 1397 | __skb_queue_tail(&queue->input_pkt_queue, skb); |
1479 | #ifndef OFFLINE_SAMPLE | ||
1480 | get_sample_stats(this_cpu); | ||
1481 | #endif | ||
1482 | local_irq_restore(flags); | 1398 | local_irq_restore(flags); |
1483 | return queue->cng_level; | 1399 | return NET_RX_SUCCESS; |
1484 | } | 1400 | } |
1485 | 1401 | ||
1486 | if (queue->throttle) | ||
1487 | queue->throttle = 0; | ||
1488 | |||
1489 | netif_rx_schedule(&queue->backlog_dev); | 1402 | netif_rx_schedule(&queue->backlog_dev); |
1490 | goto enqueue; | 1403 | goto enqueue; |
1491 | } | 1404 | } |
1492 | 1405 | ||
1493 | if (!queue->throttle) { | ||
1494 | queue->throttle = 1; | ||
1495 | __get_cpu_var(netdev_rx_stat).throttled++; | ||
1496 | } | ||
1497 | |||
1498 | drop: | ||
1499 | __get_cpu_var(netdev_rx_stat).dropped++; | 1406 | __get_cpu_var(netdev_rx_stat).dropped++; |
1500 | local_irq_restore(flags); | 1407 | local_irq_restore(flags); |
1501 | 1408 | ||
@@ -1780,8 +1687,6 @@ job_done: | |||
1780 | smp_mb__before_clear_bit(); | 1687 | smp_mb__before_clear_bit(); |
1781 | netif_poll_enable(backlog_dev); | 1688 | netif_poll_enable(backlog_dev); |
1782 | 1689 | ||
1783 | if (queue->throttle) | ||
1784 | queue->throttle = 0; | ||
1785 | local_irq_enable(); | 1690 | local_irq_enable(); |
1786 | return 0; | 1691 | return 0; |
1787 | } | 1692 | } |
@@ -1790,9 +1695,9 @@ static void net_rx_action(struct softirq_action *h) | |||
1790 | { | 1695 | { |
1791 | struct softnet_data *queue = &__get_cpu_var(softnet_data); | 1696 | struct softnet_data *queue = &__get_cpu_var(softnet_data); |
1792 | unsigned long start_time = jiffies; | 1697 | unsigned long start_time = jiffies; |
1793 | int budget = netdev_max_backlog; | 1698 | int budget = netdev_budget; |
1699 | void *have; | ||
1794 | 1700 | ||
1795 | |||
1796 | local_irq_disable(); | 1701 | local_irq_disable(); |
1797 | 1702 | ||
1798 | while (!list_empty(&queue->poll_list)) { | 1703 | while (!list_empty(&queue->poll_list)) { |
@@ -1805,10 +1710,10 @@ static void net_rx_action(struct softirq_action *h) | |||
1805 | 1710 | ||
1806 | dev = list_entry(queue->poll_list.next, | 1711 | dev = list_entry(queue->poll_list.next, |
1807 | struct net_device, poll_list); | 1712 | struct net_device, poll_list); |
1808 | netpoll_poll_lock(dev); | 1713 | have = netpoll_poll_lock(dev); |
1809 | 1714 | ||
1810 | if (dev->quota <= 0 || dev->poll(dev, &budget)) { | 1715 | if (dev->quota <= 0 || dev->poll(dev, &budget)) { |
1811 | netpoll_poll_unlock(dev); | 1716 | netpoll_poll_unlock(have); |
1812 | local_irq_disable(); | 1717 | local_irq_disable(); |
1813 | list_del(&dev->poll_list); | 1718 | list_del(&dev->poll_list); |
1814 | list_add_tail(&dev->poll_list, &queue->poll_list); | 1719 | list_add_tail(&dev->poll_list, &queue->poll_list); |
@@ -1817,7 +1722,7 @@ static void net_rx_action(struct softirq_action *h) | |||
1817 | else | 1722 | else |
1818 | dev->quota = dev->weight; | 1723 | dev->quota = dev->weight; |
1819 | } else { | 1724 | } else { |
1820 | netpoll_poll_unlock(dev); | 1725 | netpoll_poll_unlock(have); |
1821 | dev_put(dev); | 1726 | dev_put(dev); |
1822 | local_irq_disable(); | 1727 | local_irq_disable(); |
1823 | } | 1728 | } |
@@ -2055,15 +1960,9 @@ static int softnet_seq_show(struct seq_file *seq, void *v) | |||
2055 | struct netif_rx_stats *s = v; | 1960 | struct netif_rx_stats *s = v; |
2056 | 1961 | ||
2057 | seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", | 1962 | seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n", |
2058 | s->total, s->dropped, s->time_squeeze, s->throttled, | 1963 | s->total, s->dropped, s->time_squeeze, 0, |
2059 | s->fastroute_hit, s->fastroute_success, s->fastroute_defer, | 1964 | 0, 0, 0, 0, /* was fastroute */ |
2060 | s->fastroute_deferred_out, | 1965 | s->cpu_collision ); |
2061 | #if 0 | ||
2062 | s->fastroute_latency_reduction | ||
2063 | #else | ||
2064 | s->cpu_collision | ||
2065 | #endif | ||
2066 | ); | ||
2067 | return 0; | 1966 | return 0; |
2068 | } | 1967 | } |
2069 | 1968 | ||
@@ -2190,10 +2089,11 @@ void dev_set_promiscuity(struct net_device *dev, int inc) | |||
2190 | { | 2089 | { |
2191 | unsigned short old_flags = dev->flags; | 2090 | unsigned short old_flags = dev->flags; |
2192 | 2091 | ||
2193 | dev->flags |= IFF_PROMISC; | ||
2194 | if ((dev->promiscuity += inc) == 0) | 2092 | if ((dev->promiscuity += inc) == 0) |
2195 | dev->flags &= ~IFF_PROMISC; | 2093 | dev->flags &= ~IFF_PROMISC; |
2196 | if (dev->flags ^ old_flags) { | 2094 | else |
2095 | dev->flags |= IFF_PROMISC; | ||
2096 | if (dev->flags != old_flags) { | ||
2197 | dev_mc_upload(dev); | 2097 | dev_mc_upload(dev); |
2198 | printk(KERN_INFO "device %s %s promiscuous mode\n", | 2098 | printk(KERN_INFO "device %s %s promiscuous mode\n", |
2199 | dev->name, (dev->flags & IFF_PROMISC) ? "entered" : | 2099 | dev->name, (dev->flags & IFF_PROMISC) ? "entered" : |
@@ -3305,9 +3205,6 @@ static int __init net_dev_init(void) | |||
3305 | 3205 | ||
3306 | queue = &per_cpu(softnet_data, i); | 3206 | queue = &per_cpu(softnet_data, i); |
3307 | skb_queue_head_init(&queue->input_pkt_queue); | 3207 | skb_queue_head_init(&queue->input_pkt_queue); |
3308 | queue->throttle = 0; | ||
3309 | queue->cng_level = 0; | ||
3310 | queue->avg_blog = 10; /* arbitrary non-zero */ | ||
3311 | queue->completion_queue = NULL; | 3208 | queue->completion_queue = NULL; |
3312 | INIT_LIST_HEAD(&queue->poll_list); | 3209 | INIT_LIST_HEAD(&queue->poll_list); |
3313 | set_bit(__LINK_STATE_START, &queue->backlog_dev.state); | 3210 | set_bit(__LINK_STATE_START, &queue->backlog_dev.state); |
@@ -3316,11 +3213,6 @@ static int __init net_dev_init(void) | |||
3316 | atomic_set(&queue->backlog_dev.refcnt, 1); | 3213 | atomic_set(&queue->backlog_dev.refcnt, 1); |
3317 | } | 3214 | } |
3318 | 3215 | ||
3319 | #ifdef OFFLINE_SAMPLE | ||
3320 | samp_timer.expires = jiffies + (10 * HZ); | ||
3321 | add_timer(&samp_timer); | ||
3322 | #endif | ||
3323 | |||
3324 | dev_boot_phase = 0; | 3216 | dev_boot_phase = 0; |
3325 | 3217 | ||
3326 | open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); | 3218 | open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); |
diff --git a/net/core/dst.c b/net/core/dst.c index fc434ade52..334790da9f 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -45,6 +45,7 @@ static struct timer_list dst_gc_timer = | |||
45 | static void dst_run_gc(unsigned long dummy) | 45 | static void dst_run_gc(unsigned long dummy) |
46 | { | 46 | { |
47 | int delayed = 0; | 47 | int delayed = 0; |
48 | int work_performed; | ||
48 | struct dst_entry * dst, **dstp; | 49 | struct dst_entry * dst, **dstp; |
49 | 50 | ||
50 | if (!spin_trylock(&dst_lock)) { | 51 | if (!spin_trylock(&dst_lock)) { |
@@ -52,9 +53,9 @@ static void dst_run_gc(unsigned long dummy) | |||
52 | return; | 53 | return; |
53 | } | 54 | } |
54 | 55 | ||
55 | |||
56 | del_timer(&dst_gc_timer); | 56 | del_timer(&dst_gc_timer); |
57 | dstp = &dst_garbage_list; | 57 | dstp = &dst_garbage_list; |
58 | work_performed = 0; | ||
58 | while ((dst = *dstp) != NULL) { | 59 | while ((dst = *dstp) != NULL) { |
59 | if (atomic_read(&dst->__refcnt)) { | 60 | if (atomic_read(&dst->__refcnt)) { |
60 | dstp = &dst->next; | 61 | dstp = &dst->next; |
@@ -62,6 +63,7 @@ static void dst_run_gc(unsigned long dummy) | |||
62 | continue; | 63 | continue; |
63 | } | 64 | } |
64 | *dstp = dst->next; | 65 | *dstp = dst->next; |
66 | work_performed = 1; | ||
65 | 67 | ||
66 | dst = dst_destroy(dst); | 68 | dst = dst_destroy(dst); |
67 | if (dst) { | 69 | if (dst) { |
@@ -86,9 +88,14 @@ static void dst_run_gc(unsigned long dummy) | |||
86 | dst_gc_timer_inc = DST_GC_MAX; | 88 | dst_gc_timer_inc = DST_GC_MAX; |
87 | goto out; | 89 | goto out; |
88 | } | 90 | } |
89 | if ((dst_gc_timer_expires += dst_gc_timer_inc) > DST_GC_MAX) | 91 | if (!work_performed) { |
90 | dst_gc_timer_expires = DST_GC_MAX; | 92 | if ((dst_gc_timer_expires += dst_gc_timer_inc) > DST_GC_MAX) |
91 | dst_gc_timer_inc += DST_GC_INC; | 93 | dst_gc_timer_expires = DST_GC_MAX; |
94 | dst_gc_timer_inc += DST_GC_INC; | ||
95 | } else { | ||
96 | dst_gc_timer_inc = DST_GC_INC; | ||
97 | dst_gc_timer_expires = DST_GC_MIN; | ||
98 | } | ||
92 | dst_gc_timer.expires = jiffies + dst_gc_timer_expires; | 99 | dst_gc_timer.expires = jiffies + dst_gc_timer_expires; |
93 | #if RT_CACHE_DEBUG >= 2 | 100 | #if RT_CACHE_DEBUG >= 2 |
94 | printk("dst_total: %d/%d %ld\n", | 101 | printk("dst_total: %d/%d %ld\n", |
diff --git a/net/core/filter.c b/net/core/filter.c index f3b88205ac..cd91a24f97 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/filter.h> | 36 | #include <linux/filter.h> |
37 | 37 | ||
38 | /* No hurry in this branch */ | 38 | /* No hurry in this branch */ |
39 | static u8 *load_pointer(struct sk_buff *skb, int k) | 39 | static void *__load_pointer(struct sk_buff *skb, int k) |
40 | { | 40 | { |
41 | u8 *ptr = NULL; | 41 | u8 *ptr = NULL; |
42 | 42 | ||
@@ -50,6 +50,18 @@ static u8 *load_pointer(struct sk_buff *skb, int k) | |||
50 | return NULL; | 50 | return NULL; |
51 | } | 51 | } |
52 | 52 | ||
53 | static inline void *load_pointer(struct sk_buff *skb, int k, | ||
54 | unsigned int size, void *buffer) | ||
55 | { | ||
56 | if (k >= 0) | ||
57 | return skb_header_pointer(skb, k, size, buffer); | ||
58 | else { | ||
59 | if (k >= SKF_AD_OFF) | ||
60 | return NULL; | ||
61 | return __load_pointer(skb, k); | ||
62 | } | ||
63 | } | ||
64 | |||
53 | /** | 65 | /** |
54 | * sk_run_filter - run a filter on a socket | 66 | * sk_run_filter - run a filter on a socket |
55 | * @skb: buffer to run the filter on | 67 | * @skb: buffer to run the filter on |
@@ -64,15 +76,12 @@ static u8 *load_pointer(struct sk_buff *skb, int k) | |||
64 | 76 | ||
65 | int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) | 77 | int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) |
66 | { | 78 | { |
67 | unsigned char *data = skb->data; | ||
68 | /* len is UNSIGNED. Byte wide insns relies only on implicit | ||
69 | type casts to prevent reading arbitrary memory locations. | ||
70 | */ | ||
71 | unsigned int len = skb->len-skb->data_len; | ||
72 | struct sock_filter *fentry; /* We walk down these */ | 79 | struct sock_filter *fentry; /* We walk down these */ |
80 | void *ptr; | ||
73 | u32 A = 0; /* Accumulator */ | 81 | u32 A = 0; /* Accumulator */ |
74 | u32 X = 0; /* Index Register */ | 82 | u32 X = 0; /* Index Register */ |
75 | u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ | 83 | u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ |
84 | u32 tmp; | ||
76 | int k; | 85 | int k; |
77 | int pc; | 86 | int pc; |
78 | 87 | ||
@@ -168,86 +177,35 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) | |||
168 | case BPF_LD|BPF_W|BPF_ABS: | 177 | case BPF_LD|BPF_W|BPF_ABS: |
169 | k = fentry->k; | 178 | k = fentry->k; |
170 | load_w: | 179 | load_w: |
171 | if (k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) { | 180 | ptr = load_pointer(skb, k, 4, &tmp); |
172 | A = ntohl(*(u32*)&data[k]); | 181 | if (ptr != NULL) { |
182 | A = ntohl(*(u32 *)ptr); | ||
173 | continue; | 183 | continue; |
174 | } | 184 | } |
175 | if (k < 0) { | ||
176 | u8 *ptr; | ||
177 | |||
178 | if (k >= SKF_AD_OFF) | ||
179 | break; | ||
180 | ptr = load_pointer(skb, k); | ||
181 | if (ptr) { | ||
182 | A = ntohl(*(u32*)ptr); | ||
183 | continue; | ||
184 | } | ||
185 | } else { | ||
186 | u32 _tmp, *p; | ||
187 | p = skb_header_pointer(skb, k, 4, &_tmp); | ||
188 | if (p != NULL) { | ||
189 | A = ntohl(*p); | ||
190 | continue; | ||
191 | } | ||
192 | } | ||
193 | return 0; | 185 | return 0; |
194 | case BPF_LD|BPF_H|BPF_ABS: | 186 | case BPF_LD|BPF_H|BPF_ABS: |
195 | k = fentry->k; | 187 | k = fentry->k; |
196 | load_h: | 188 | load_h: |
197 | if (k >= 0 && (unsigned int)(k + sizeof(u16)) <= len) { | 189 | ptr = load_pointer(skb, k, 2, &tmp); |
198 | A = ntohs(*(u16*)&data[k]); | 190 | if (ptr != NULL) { |
191 | A = ntohs(*(u16 *)ptr); | ||
199 | continue; | 192 | continue; |
200 | } | 193 | } |
201 | if (k < 0) { | ||
202 | u8 *ptr; | ||
203 | |||
204 | if (k >= SKF_AD_OFF) | ||
205 | break; | ||
206 | ptr = load_pointer(skb, k); | ||
207 | if (ptr) { | ||
208 | A = ntohs(*(u16*)ptr); | ||
209 | continue; | ||
210 | } | ||
211 | } else { | ||
212 | u16 _tmp, *p; | ||
213 | p = skb_header_pointer(skb, k, 2, &_tmp); | ||
214 | if (p != NULL) { | ||
215 | A = ntohs(*p); | ||
216 | continue; | ||
217 | } | ||
218 | } | ||
219 | return 0; | 194 | return 0; |
220 | case BPF_LD|BPF_B|BPF_ABS: | 195 | case BPF_LD|BPF_B|BPF_ABS: |
221 | k = fentry->k; | 196 | k = fentry->k; |
222 | load_b: | 197 | load_b: |
223 | if (k >= 0 && (unsigned int)k < len) { | 198 | ptr = load_pointer(skb, k, 1, &tmp); |
224 | A = data[k]; | 199 | if (ptr != NULL) { |
200 | A = *(u8 *)ptr; | ||
225 | continue; | 201 | continue; |
226 | } | 202 | } |
227 | if (k < 0) { | ||
228 | u8 *ptr; | ||
229 | |||
230 | if (k >= SKF_AD_OFF) | ||
231 | break; | ||
232 | ptr = load_pointer(skb, k); | ||
233 | if (ptr) { | ||
234 | A = *ptr; | ||
235 | continue; | ||
236 | } | ||
237 | } else { | ||
238 | u8 _tmp, *p; | ||
239 | p = skb_header_pointer(skb, k, 1, &_tmp); | ||
240 | if (p != NULL) { | ||
241 | A = *p; | ||
242 | continue; | ||
243 | } | ||
244 | } | ||
245 | return 0; | 203 | return 0; |
246 | case BPF_LD|BPF_W|BPF_LEN: | 204 | case BPF_LD|BPF_W|BPF_LEN: |
247 | A = len; | 205 | A = skb->len; |
248 | continue; | 206 | continue; |
249 | case BPF_LDX|BPF_W|BPF_LEN: | 207 | case BPF_LDX|BPF_W|BPF_LEN: |
250 | X = len; | 208 | X = skb->len; |
251 | continue; | 209 | continue; |
252 | case BPF_LD|BPF_W|BPF_IND: | 210 | case BPF_LD|BPF_W|BPF_IND: |
253 | k = X + fentry->k; | 211 | k = X + fentry->k; |
@@ -259,10 +217,12 @@ load_b: | |||
259 | k = X + fentry->k; | 217 | k = X + fentry->k; |
260 | goto load_b; | 218 | goto load_b; |
261 | case BPF_LDX|BPF_B|BPF_MSH: | 219 | case BPF_LDX|BPF_B|BPF_MSH: |
262 | if (fentry->k >= len) | 220 | ptr = load_pointer(skb, fentry->k, 1, &tmp); |
263 | return 0; | 221 | if (ptr != NULL) { |
264 | X = (data[fentry->k] & 0xf) << 2; | 222 | X = (*(u8 *)ptr & 0xf) << 2; |
265 | continue; | 223 | continue; |
224 | } | ||
225 | return 0; | ||
266 | case BPF_LD|BPF_IMM: | 226 | case BPF_LD|BPF_IMM: |
267 | A = fentry->k; | 227 | A = fentry->k; |
268 | continue; | 228 | continue; |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index f6bdcad47d..1beb782ac4 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <net/sock.h> | 32 | #include <net/sock.h> |
33 | #include <linux/rtnetlink.h> | 33 | #include <linux/rtnetlink.h> |
34 | #include <linux/random.h> | 34 | #include <linux/random.h> |
35 | #include <linux/string.h> | ||
35 | 36 | ||
36 | #define NEIGH_DEBUG 1 | 37 | #define NEIGH_DEBUG 1 |
37 | 38 | ||
@@ -1597,6 +1598,8 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, | |||
1597 | 1598 | ||
1598 | read_lock_bh(&tbl->lock); | 1599 | read_lock_bh(&tbl->lock); |
1599 | ndtmsg->ndtm_family = tbl->family; | 1600 | ndtmsg->ndtm_family = tbl->family; |
1601 | ndtmsg->ndtm_pad1 = 0; | ||
1602 | ndtmsg->ndtm_pad2 = 0; | ||
1600 | 1603 | ||
1601 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); | 1604 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); |
1602 | RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); | 1605 | RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); |
@@ -1682,6 +1685,8 @@ static int neightbl_fill_param_info(struct neigh_table *tbl, | |||
1682 | 1685 | ||
1683 | read_lock_bh(&tbl->lock); | 1686 | read_lock_bh(&tbl->lock); |
1684 | ndtmsg->ndtm_family = tbl->family; | 1687 | ndtmsg->ndtm_family = tbl->family; |
1688 | ndtmsg->ndtm_pad1 = 0; | ||
1689 | ndtmsg->ndtm_pad2 = 0; | ||
1685 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); | 1690 | RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); |
1686 | 1691 | ||
1687 | if (neightbl_fill_parms(skb, parms) < 0) | 1692 | if (neightbl_fill_parms(skb, parms) < 0) |
@@ -1871,6 +1876,8 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, | |||
1871 | struct ndmsg *ndm = NLMSG_DATA(nlh); | 1876 | struct ndmsg *ndm = NLMSG_DATA(nlh); |
1872 | 1877 | ||
1873 | ndm->ndm_family = n->ops->family; | 1878 | ndm->ndm_family = n->ops->family; |
1879 | ndm->ndm_pad1 = 0; | ||
1880 | ndm->ndm_pad2 = 0; | ||
1874 | ndm->ndm_flags = n->flags; | 1881 | ndm->ndm_flags = n->flags; |
1875 | ndm->ndm_type = n->type; | 1882 | ndm->ndm_type = n->type; |
1876 | ndm->ndm_ifindex = n->dev->ifindex; | 1883 | ndm->ndm_ifindex = n->dev->ifindex; |
@@ -2592,7 +2599,7 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | |||
2592 | t->neigh_vars[17].extra1 = dev; | 2599 | t->neigh_vars[17].extra1 = dev; |
2593 | } | 2600 | } |
2594 | 2601 | ||
2595 | dev_name = net_sysctl_strdup(dev_name_source); | 2602 | dev_name = kstrdup(dev_name_source, GFP_KERNEL); |
2596 | if (!dev_name) { | 2603 | if (!dev_name) { |
2597 | err = -ENOBUFS; | 2604 | err = -ENOBUFS; |
2598 | goto free; | 2605 | goto free; |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index a119696d55..a1a9a7abff 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #define MAX_UDP_CHUNK 1460 | 33 | #define MAX_UDP_CHUNK 1460 |
34 | #define MAX_SKBS 32 | 34 | #define MAX_SKBS 32 |
35 | #define MAX_QUEUE_DEPTH (MAX_SKBS / 2) | 35 | #define MAX_QUEUE_DEPTH (MAX_SKBS / 2) |
36 | #define MAX_RETRIES 20000 | ||
36 | 37 | ||
37 | static DEFINE_SPINLOCK(skb_list_lock); | 38 | static DEFINE_SPINLOCK(skb_list_lock); |
38 | static int nr_skbs; | 39 | static int nr_skbs; |
@@ -130,19 +131,20 @@ static int checksum_udp(struct sk_buff *skb, struct udphdr *uh, | |||
130 | */ | 131 | */ |
131 | static void poll_napi(struct netpoll *np) | 132 | static void poll_napi(struct netpoll *np) |
132 | { | 133 | { |
134 | struct netpoll_info *npinfo = np->dev->npinfo; | ||
133 | int budget = 16; | 135 | int budget = 16; |
134 | 136 | ||
135 | if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) && | 137 | if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) && |
136 | np->poll_owner != smp_processor_id() && | 138 | npinfo->poll_owner != smp_processor_id() && |
137 | spin_trylock(&np->poll_lock)) { | 139 | spin_trylock(&npinfo->poll_lock)) { |
138 | np->rx_flags |= NETPOLL_RX_DROP; | 140 | npinfo->rx_flags |= NETPOLL_RX_DROP; |
139 | atomic_inc(&trapped); | 141 | atomic_inc(&trapped); |
140 | 142 | ||
141 | np->dev->poll(np->dev, &budget); | 143 | np->dev->poll(np->dev, &budget); |
142 | 144 | ||
143 | atomic_dec(&trapped); | 145 | atomic_dec(&trapped); |
144 | np->rx_flags &= ~NETPOLL_RX_DROP; | 146 | npinfo->rx_flags &= ~NETPOLL_RX_DROP; |
145 | spin_unlock(&np->poll_lock); | 147 | spin_unlock(&npinfo->poll_lock); |
146 | } | 148 | } |
147 | } | 149 | } |
148 | 150 | ||
@@ -245,16 +247,18 @@ repeat: | |||
245 | static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) | 247 | static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) |
246 | { | 248 | { |
247 | int status; | 249 | int status; |
250 | struct netpoll_info *npinfo; | ||
248 | 251 | ||
249 | repeat: | 252 | if (!np || !np->dev || !netif_running(np->dev)) { |
250 | if(!np || !np->dev || !netif_running(np->dev)) { | ||
251 | __kfree_skb(skb); | 253 | __kfree_skb(skb); |
252 | return; | 254 | return; |
253 | } | 255 | } |
254 | 256 | ||
257 | npinfo = np->dev->npinfo; | ||
258 | |||
255 | /* avoid recursion */ | 259 | /* avoid recursion */ |
256 | if(np->poll_owner == smp_processor_id() || | 260 | if (npinfo->poll_owner == smp_processor_id() || |
257 | np->dev->xmit_lock_owner == smp_processor_id()) { | 261 | np->dev->xmit_lock_owner == smp_processor_id()) { |
258 | if (np->drop) | 262 | if (np->drop) |
259 | np->drop(skb); | 263 | np->drop(skb); |
260 | else | 264 | else |
@@ -262,30 +266,37 @@ repeat: | |||
262 | return; | 266 | return; |
263 | } | 267 | } |
264 | 268 | ||
265 | spin_lock(&np->dev->xmit_lock); | 269 | do { |
266 | np->dev->xmit_lock_owner = smp_processor_id(); | 270 | npinfo->tries--; |
271 | spin_lock(&np->dev->xmit_lock); | ||
272 | np->dev->xmit_lock_owner = smp_processor_id(); | ||
267 | 273 | ||
268 | /* | 274 | /* |
269 | * network drivers do not expect to be called if the queue is | 275 | * network drivers do not expect to be called if the queue is |
270 | * stopped. | 276 | * stopped. |
271 | */ | 277 | */ |
272 | if (netif_queue_stopped(np->dev)) { | 278 | if (netif_queue_stopped(np->dev)) { |
279 | np->dev->xmit_lock_owner = -1; | ||
280 | spin_unlock(&np->dev->xmit_lock); | ||
281 | netpoll_poll(np); | ||
282 | udelay(50); | ||
283 | continue; | ||
284 | } | ||
285 | |||
286 | status = np->dev->hard_start_xmit(skb, np->dev); | ||
273 | np->dev->xmit_lock_owner = -1; | 287 | np->dev->xmit_lock_owner = -1; |
274 | spin_unlock(&np->dev->xmit_lock); | 288 | spin_unlock(&np->dev->xmit_lock); |
275 | 289 | ||
276 | netpoll_poll(np); | 290 | /* success */ |
277 | goto repeat; | 291 | if(!status) { |
278 | } | 292 | npinfo->tries = MAX_RETRIES; /* reset */ |
279 | 293 | return; | |
280 | status = np->dev->hard_start_xmit(skb, np->dev); | 294 | } |
281 | np->dev->xmit_lock_owner = -1; | ||
282 | spin_unlock(&np->dev->xmit_lock); | ||
283 | 295 | ||
284 | /* transmit busy */ | 296 | /* transmit busy */ |
285 | if(status) { | ||
286 | netpoll_poll(np); | 297 | netpoll_poll(np); |
287 | goto repeat; | 298 | udelay(50); |
288 | } | 299 | } while (npinfo->tries > 0); |
289 | } | 300 | } |
290 | 301 | ||
291 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len) | 302 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len) |
@@ -341,14 +352,18 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) | |||
341 | 352 | ||
342 | static void arp_reply(struct sk_buff *skb) | 353 | static void arp_reply(struct sk_buff *skb) |
343 | { | 354 | { |
355 | struct netpoll_info *npinfo = skb->dev->npinfo; | ||
344 | struct arphdr *arp; | 356 | struct arphdr *arp; |
345 | unsigned char *arp_ptr; | 357 | unsigned char *arp_ptr; |
346 | int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; | 358 | int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; |
347 | u32 sip, tip; | 359 | u32 sip, tip; |
348 | struct sk_buff *send_skb; | 360 | struct sk_buff *send_skb; |
349 | struct netpoll *np = skb->dev->np; | 361 | struct netpoll *np = NULL; |
350 | 362 | ||
351 | if (!np) return; | 363 | if (npinfo->rx_np && npinfo->rx_np->dev == skb->dev) |
364 | np = npinfo->rx_np; | ||
365 | if (!np) | ||
366 | return; | ||
352 | 367 | ||
353 | /* No arp on this interface */ | 368 | /* No arp on this interface */ |
354 | if (skb->dev->flags & IFF_NOARP) | 369 | if (skb->dev->flags & IFF_NOARP) |
@@ -429,9 +444,9 @@ int __netpoll_rx(struct sk_buff *skb) | |||
429 | int proto, len, ulen; | 444 | int proto, len, ulen; |
430 | struct iphdr *iph; | 445 | struct iphdr *iph; |
431 | struct udphdr *uh; | 446 | struct udphdr *uh; |
432 | struct netpoll *np = skb->dev->np; | 447 | struct netpoll *np = skb->dev->npinfo->rx_np; |
433 | 448 | ||
434 | if (!np->rx_hook) | 449 | if (!np) |
435 | goto out; | 450 | goto out; |
436 | if (skb->dev->type != ARPHRD_ETHER) | 451 | if (skb->dev->type != ARPHRD_ETHER) |
437 | goto out; | 452 | goto out; |
@@ -611,9 +626,8 @@ int netpoll_setup(struct netpoll *np) | |||
611 | { | 626 | { |
612 | struct net_device *ndev = NULL; | 627 | struct net_device *ndev = NULL; |
613 | struct in_device *in_dev; | 628 | struct in_device *in_dev; |
614 | 629 | struct netpoll_info *npinfo; | |
615 | np->poll_lock = SPIN_LOCK_UNLOCKED; | 630 | unsigned long flags; |
616 | np->poll_owner = -1; | ||
617 | 631 | ||
618 | if (np->dev_name) | 632 | if (np->dev_name) |
619 | ndev = dev_get_by_name(np->dev_name); | 633 | ndev = dev_get_by_name(np->dev_name); |
@@ -624,7 +638,19 @@ int netpoll_setup(struct netpoll *np) | |||
624 | } | 638 | } |
625 | 639 | ||
626 | np->dev = ndev; | 640 | np->dev = ndev; |
627 | ndev->np = np; | 641 | if (!ndev->npinfo) { |
642 | npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); | ||
643 | if (!npinfo) | ||
644 | goto release; | ||
645 | |||
646 | npinfo->rx_flags = 0; | ||
647 | npinfo->rx_np = NULL; | ||
648 | npinfo->poll_lock = SPIN_LOCK_UNLOCKED; | ||
649 | npinfo->poll_owner = -1; | ||
650 | npinfo->tries = MAX_RETRIES; | ||
651 | npinfo->rx_lock = SPIN_LOCK_UNLOCKED; | ||
652 | } else | ||
653 | npinfo = ndev->npinfo; | ||
628 | 654 | ||
629 | if (!ndev->poll_controller) { | 655 | if (!ndev->poll_controller) { |
630 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", | 656 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", |
@@ -692,13 +718,27 @@ int netpoll_setup(struct netpoll *np) | |||
692 | np->name, HIPQUAD(np->local_ip)); | 718 | np->name, HIPQUAD(np->local_ip)); |
693 | } | 719 | } |
694 | 720 | ||
695 | if(np->rx_hook) | 721 | if (np->rx_hook) { |
696 | np->rx_flags = NETPOLL_RX_ENABLED; | 722 | spin_lock_irqsave(&npinfo->rx_lock, flags); |
723 | npinfo->rx_flags |= NETPOLL_RX_ENABLED; | ||
724 | npinfo->rx_np = np; | ||
725 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
726 | } | ||
727 | |||
728 | /* fill up the skb queue */ | ||
729 | refill_skbs(); | ||
730 | |||
731 | /* last thing to do is link it to the net device structure */ | ||
732 | ndev->npinfo = npinfo; | ||
733 | |||
734 | /* avoid racing with NAPI reading npinfo */ | ||
735 | synchronize_rcu(); | ||
697 | 736 | ||
698 | return 0; | 737 | return 0; |
699 | 738 | ||
700 | release: | 739 | release: |
701 | ndev->np = NULL; | 740 | if (!ndev->npinfo) |
741 | kfree(npinfo); | ||
702 | np->dev = NULL; | 742 | np->dev = NULL; |
703 | dev_put(ndev); | 743 | dev_put(ndev); |
704 | return -1; | 744 | return -1; |
@@ -706,9 +746,20 @@ int netpoll_setup(struct netpoll *np) | |||
706 | 746 | ||
707 | void netpoll_cleanup(struct netpoll *np) | 747 | void netpoll_cleanup(struct netpoll *np) |
708 | { | 748 | { |
709 | if (np->dev) | 749 | struct netpoll_info *npinfo; |
710 | np->dev->np = NULL; | 750 | unsigned long flags; |
711 | dev_put(np->dev); | 751 | |
752 | if (np->dev) { | ||
753 | npinfo = np->dev->npinfo; | ||
754 | if (npinfo && npinfo->rx_np == np) { | ||
755 | spin_lock_irqsave(&npinfo->rx_lock, flags); | ||
756 | npinfo->rx_np = NULL; | ||
757 | npinfo->rx_flags &= ~NETPOLL_RX_ENABLED; | ||
758 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
759 | } | ||
760 | dev_put(np->dev); | ||
761 | } | ||
762 | |||
712 | np->dev = NULL; | 763 | np->dev = NULL; |
713 | } | 764 | } |
714 | 765 | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index c57b06bc79..8eb083b604 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -151,7 +151,7 @@ | |||
151 | #include <asm/timex.h> | 151 | #include <asm/timex.h> |
152 | 152 | ||
153 | 153 | ||
154 | #define VERSION "pktgen v2.61: Packet Generator for packet performance testing.\n" | 154 | #define VERSION "pktgen v2.62: Packet Generator for packet performance testing.\n" |
155 | 155 | ||
156 | /* #define PG_DEBUG(a) a */ | 156 | /* #define PG_DEBUG(a) a */ |
157 | #define PG_DEBUG(a) | 157 | #define PG_DEBUG(a) |
@@ -363,7 +363,7 @@ struct pktgen_thread { | |||
363 | * All Rights Reserved. | 363 | * All Rights Reserved. |
364 | * | 364 | * |
365 | */ | 365 | */ |
366 | inline static s64 divremdi3(s64 x, s64 y, int type) | 366 | static inline s64 divremdi3(s64 x, s64 y, int type) |
367 | { | 367 | { |
368 | u64 a = (x < 0) ? -x : x; | 368 | u64 a = (x < 0) ? -x : x; |
369 | u64 b = (y < 0) ? -y : y; | 369 | u64 b = (y < 0) ? -y : y; |
@@ -1921,6 +1921,11 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
1921 | struct iphdr *iph; | 1921 | struct iphdr *iph; |
1922 | struct pktgen_hdr *pgh = NULL; | 1922 | struct pktgen_hdr *pgh = NULL; |
1923 | 1923 | ||
1924 | /* Update any of the values, used when we're incrementing various | ||
1925 | * fields. | ||
1926 | */ | ||
1927 | mod_cur_headers(pkt_dev); | ||
1928 | |||
1924 | skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC); | 1929 | skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC); |
1925 | if (!skb) { | 1930 | if (!skb) { |
1926 | sprintf(pkt_dev->result, "No memory"); | 1931 | sprintf(pkt_dev->result, "No memory"); |
@@ -1934,11 +1939,6 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
1934 | iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)); | 1939 | iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr)); |
1935 | udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); | 1940 | udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); |
1936 | 1941 | ||
1937 | /* Update any of the values, used when we're incrementing various | ||
1938 | * fields. | ||
1939 | */ | ||
1940 | mod_cur_headers(pkt_dev); | ||
1941 | |||
1942 | memcpy(eth, pkt_dev->hh, 12); | 1942 | memcpy(eth, pkt_dev->hh, 12); |
1943 | *(u16*)ð[12] = __constant_htons(ETH_P_IP); | 1943 | *(u16*)ð[12] = __constant_htons(ETH_P_IP); |
1944 | 1944 | ||
@@ -2192,7 +2192,12 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2192 | int datalen; | 2192 | int datalen; |
2193 | struct ipv6hdr *iph; | 2193 | struct ipv6hdr *iph; |
2194 | struct pktgen_hdr *pgh = NULL; | 2194 | struct pktgen_hdr *pgh = NULL; |
2195 | 2195 | ||
2196 | /* Update any of the values, used when we're incrementing various | ||
2197 | * fields. | ||
2198 | */ | ||
2199 | mod_cur_headers(pkt_dev); | ||
2200 | |||
2196 | skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC); | 2201 | skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC); |
2197 | if (!skb) { | 2202 | if (!skb) { |
2198 | sprintf(pkt_dev->result, "No memory"); | 2203 | sprintf(pkt_dev->result, "No memory"); |
@@ -2206,17 +2211,9 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2206 | iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr)); | 2211 | iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr)); |
2207 | udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); | 2212 | udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); |
2208 | 2213 | ||
2209 | |||
2210 | /* Update any of the values, used when we're incrementing various | ||
2211 | * fields. | ||
2212 | */ | ||
2213 | mod_cur_headers(pkt_dev); | ||
2214 | |||
2215 | |||
2216 | memcpy(eth, pkt_dev->hh, 12); | 2214 | memcpy(eth, pkt_dev->hh, 12); |
2217 | *(u16*)ð[12] = __constant_htons(ETH_P_IPV6); | 2215 | *(u16*)ð[12] = __constant_htons(ETH_P_IPV6); |
2218 | 2216 | ||
2219 | |||
2220 | datalen = pkt_dev->cur_pkt_size-14- | 2217 | datalen = pkt_dev->cur_pkt_size-14- |
2221 | sizeof(struct ipv6hdr)-sizeof(struct udphdr); /* Eth + IPh + UDPh */ | 2218 | sizeof(struct ipv6hdr)-sizeof(struct udphdr); /* Eth + IPh + UDPh */ |
2222 | 2219 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e013d836a7..4b1bb30e63 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -126,6 +126,7 @@ void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data | |||
126 | rta->rta_type = attrtype; | 126 | rta->rta_type = attrtype; |
127 | rta->rta_len = size; | 127 | rta->rta_len = size; |
128 | memcpy(RTA_DATA(rta), data, attrlen); | 128 | memcpy(RTA_DATA(rta), data, attrlen); |
129 | memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); | ||
129 | } | 130 | } |
130 | 131 | ||
131 | size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) | 132 | size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) |
@@ -188,6 +189,7 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
188 | nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags); | 189 | nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags); |
189 | r = NLMSG_DATA(nlh); | 190 | r = NLMSG_DATA(nlh); |
190 | r->ifi_family = AF_UNSPEC; | 191 | r->ifi_family = AF_UNSPEC; |
192 | r->__ifi_pad = 0; | ||
191 | r->ifi_type = dev->type; | 193 | r->ifi_type = dev->type; |
192 | r->ifi_index = dev->ifindex; | 194 | r->ifi_index = dev->ifindex; |
193 | r->ifi_flags = dev_get_flags(dev); | 195 | r->ifi_flags = dev_get_flags(dev); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 6d68c03bc0..7eab867ede 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -129,7 +129,7 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here) | |||
129 | * Buffers may only be allocated from interrupts using a @gfp_mask of | 129 | * Buffers may only be allocated from interrupts using a @gfp_mask of |
130 | * %GFP_ATOMIC. | 130 | * %GFP_ATOMIC. |
131 | */ | 131 | */ |
132 | struct sk_buff *alloc_skb(unsigned int size, int gfp_mask) | 132 | struct sk_buff *alloc_skb(unsigned int size, unsigned int __nocast gfp_mask) |
133 | { | 133 | { |
134 | struct sk_buff *skb; | 134 | struct sk_buff *skb; |
135 | u8 *data; | 135 | u8 *data; |
@@ -182,7 +182,8 @@ nodata: | |||
182 | * %GFP_ATOMIC. | 182 | * %GFP_ATOMIC. |
183 | */ | 183 | */ |
184 | struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, | 184 | struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, |
185 | unsigned int size, int gfp_mask) | 185 | unsigned int size, |
186 | unsigned int __nocast gfp_mask) | ||
186 | { | 187 | { |
187 | struct sk_buff *skb; | 188 | struct sk_buff *skb; |
188 | u8 *data; | 189 | u8 *data; |
@@ -322,7 +323,7 @@ void __kfree_skb(struct sk_buff *skb) | |||
322 | * %GFP_ATOMIC. | 323 | * %GFP_ATOMIC. |
323 | */ | 324 | */ |
324 | 325 | ||
325 | struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) | 326 | struct sk_buff *skb_clone(struct sk_buff *skb, unsigned int __nocast gfp_mask) |
326 | { | 327 | { |
327 | struct sk_buff *n = kmem_cache_alloc(skbuff_head_cache, gfp_mask); | 328 | struct sk_buff *n = kmem_cache_alloc(skbuff_head_cache, gfp_mask); |
328 | 329 | ||
@@ -357,7 +358,6 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) | |||
357 | C(ip_summed); | 358 | C(ip_summed); |
358 | C(priority); | 359 | C(priority); |
359 | C(protocol); | 360 | C(protocol); |
360 | C(security); | ||
361 | n->destructor = NULL; | 361 | n->destructor = NULL; |
362 | #ifdef CONFIG_NETFILTER | 362 | #ifdef CONFIG_NETFILTER |
363 | C(nfmark); | 363 | C(nfmark); |
@@ -377,8 +377,8 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) | |||
377 | C(tc_index); | 377 | C(tc_index); |
378 | #ifdef CONFIG_NET_CLS_ACT | 378 | #ifdef CONFIG_NET_CLS_ACT |
379 | n->tc_verd = SET_TC_VERD(skb->tc_verd,0); | 379 | n->tc_verd = SET_TC_VERD(skb->tc_verd,0); |
380 | n->tc_verd = CLR_TC_OK2MUNGE(skb->tc_verd); | 380 | n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd); |
381 | n->tc_verd = CLR_TC_MUNGED(skb->tc_verd); | 381 | n->tc_verd = CLR_TC_MUNGED(n->tc_verd); |
382 | C(input_dev); | 382 | C(input_dev); |
383 | C(tc_classid); | 383 | C(tc_classid); |
384 | #endif | 384 | #endif |
@@ -422,7 +422,6 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
422 | new->pkt_type = old->pkt_type; | 422 | new->pkt_type = old->pkt_type; |
423 | new->stamp = old->stamp; | 423 | new->stamp = old->stamp; |
424 | new->destructor = NULL; | 424 | new->destructor = NULL; |
425 | new->security = old->security; | ||
426 | #ifdef CONFIG_NETFILTER | 425 | #ifdef CONFIG_NETFILTER |
427 | new->nfmark = old->nfmark; | 426 | new->nfmark = old->nfmark; |
428 | new->nfcache = old->nfcache; | 427 | new->nfcache = old->nfcache; |
@@ -462,7 +461,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
462 | * header is going to be modified. Use pskb_copy() instead. | 461 | * header is going to be modified. Use pskb_copy() instead. |
463 | */ | 462 | */ |
464 | 463 | ||
465 | struct sk_buff *skb_copy(const struct sk_buff *skb, int gfp_mask) | 464 | struct sk_buff *skb_copy(const struct sk_buff *skb, unsigned int __nocast gfp_mask) |
466 | { | 465 | { |
467 | int headerlen = skb->data - skb->head; | 466 | int headerlen = skb->data - skb->head; |
468 | /* | 467 | /* |
@@ -501,7 +500,7 @@ struct sk_buff *skb_copy(const struct sk_buff *skb, int gfp_mask) | |||
501 | * The returned buffer has a reference count of 1. | 500 | * The returned buffer has a reference count of 1. |
502 | */ | 501 | */ |
503 | 502 | ||
504 | struct sk_buff *pskb_copy(struct sk_buff *skb, int gfp_mask) | 503 | struct sk_buff *pskb_copy(struct sk_buff *skb, unsigned int __nocast gfp_mask) |
505 | { | 504 | { |
506 | /* | 505 | /* |
507 | * Allocate the copy buffer | 506 | * Allocate the copy buffer |
@@ -559,7 +558,8 @@ out: | |||
559 | * reloaded after call to this function. | 558 | * reloaded after call to this function. |
560 | */ | 559 | */ |
561 | 560 | ||
562 | int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, int gfp_mask) | 561 | int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, |
562 | unsigned int __nocast gfp_mask) | ||
563 | { | 563 | { |
564 | int i; | 564 | int i; |
565 | u8 *data; | 565 | u8 *data; |
@@ -649,7 +649,8 @@ struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, unsigned int headroom) | |||
649 | * only by netfilter in the cases when checksum is recalculated? --ANK | 649 | * only by netfilter in the cases when checksum is recalculated? --ANK |
650 | */ | 650 | */ |
651 | struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | 651 | struct sk_buff *skb_copy_expand(const struct sk_buff *skb, |
652 | int newheadroom, int newtailroom, int gfp_mask) | 652 | int newheadroom, int newtailroom, |
653 | unsigned int __nocast gfp_mask) | ||
653 | { | 654 | { |
654 | /* | 655 | /* |
655 | * Allocate the copy buffer | 656 | * Allocate the copy buffer |
@@ -1500,6 +1501,159 @@ void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len) | |||
1500 | skb_split_no_header(skb, skb1, len, pos); | 1501 | skb_split_no_header(skb, skb1, len, pos); |
1501 | } | 1502 | } |
1502 | 1503 | ||
1504 | /** | ||
1505 | * skb_prepare_seq_read - Prepare a sequential read of skb data | ||
1506 | * @skb: the buffer to read | ||
1507 | * @from: lower offset of data to be read | ||
1508 | * @to: upper offset of data to be read | ||
1509 | * @st: state variable | ||
1510 | * | ||
1511 | * Initializes the specified state variable. Must be called before | ||
1512 | * invoking skb_seq_read() for the first time. | ||
1513 | */ | ||
1514 | void skb_prepare_seq_read(struct sk_buff *skb, unsigned int from, | ||
1515 | unsigned int to, struct skb_seq_state *st) | ||
1516 | { | ||
1517 | st->lower_offset = from; | ||
1518 | st->upper_offset = to; | ||
1519 | st->root_skb = st->cur_skb = skb; | ||
1520 | st->frag_idx = st->stepped_offset = 0; | ||
1521 | st->frag_data = NULL; | ||
1522 | } | ||
1523 | |||
1524 | /** | ||
1525 | * skb_seq_read - Sequentially read skb data | ||
1526 | * @consumed: number of bytes consumed by the caller so far | ||
1527 | * @data: destination pointer for data to be returned | ||
1528 | * @st: state variable | ||
1529 | * | ||
1530 | * Reads a block of skb data at &consumed relative to the | ||
1531 | * lower offset specified to skb_prepare_seq_read(). Assigns | ||
1532 | * the head of the data block to &data and returns the length | ||
1533 | * of the block or 0 if the end of the skb data or the upper | ||
1534 | * offset has been reached. | ||
1535 | * | ||
1536 | * The caller is not required to consume all of the data | ||
1537 | * returned, i.e. &consumed is typically set to the number | ||
1538 | * of bytes already consumed and the next call to | ||
1539 | * skb_seq_read() will return the remaining part of the block. | ||
1540 | * | ||
1541 | * Note: The size of each block of data returned can be arbitary, | ||
1542 | * this limitation is the cost for zerocopy seqeuental | ||
1543 | * reads of potentially non linear data. | ||
1544 | * | ||
1545 | * Note: Fragment lists within fragments are not implemented | ||
1546 | * at the moment, state->root_skb could be replaced with | ||
1547 | * a stack for this purpose. | ||
1548 | */ | ||
1549 | unsigned int skb_seq_read(unsigned int consumed, const u8 **data, | ||
1550 | struct skb_seq_state *st) | ||
1551 | { | ||
1552 | unsigned int block_limit, abs_offset = consumed + st->lower_offset; | ||
1553 | skb_frag_t *frag; | ||
1554 | |||
1555 | if (unlikely(abs_offset >= st->upper_offset)) | ||
1556 | return 0; | ||
1557 | |||
1558 | next_skb: | ||
1559 | block_limit = skb_headlen(st->cur_skb); | ||
1560 | |||
1561 | if (abs_offset < block_limit) { | ||
1562 | *data = st->cur_skb->data + abs_offset; | ||
1563 | return block_limit - abs_offset; | ||
1564 | } | ||
1565 | |||
1566 | if (st->frag_idx == 0 && !st->frag_data) | ||
1567 | st->stepped_offset += skb_headlen(st->cur_skb); | ||
1568 | |||
1569 | while (st->frag_idx < skb_shinfo(st->cur_skb)->nr_frags) { | ||
1570 | frag = &skb_shinfo(st->cur_skb)->frags[st->frag_idx]; | ||
1571 | block_limit = frag->size + st->stepped_offset; | ||
1572 | |||
1573 | if (abs_offset < block_limit) { | ||
1574 | if (!st->frag_data) | ||
1575 | st->frag_data = kmap_skb_frag(frag); | ||
1576 | |||
1577 | *data = (u8 *) st->frag_data + frag->page_offset + | ||
1578 | (abs_offset - st->stepped_offset); | ||
1579 | |||
1580 | return block_limit - abs_offset; | ||
1581 | } | ||
1582 | |||
1583 | if (st->frag_data) { | ||
1584 | kunmap_skb_frag(st->frag_data); | ||
1585 | st->frag_data = NULL; | ||
1586 | } | ||
1587 | |||
1588 | st->frag_idx++; | ||
1589 | st->stepped_offset += frag->size; | ||
1590 | } | ||
1591 | |||
1592 | if (st->cur_skb->next) { | ||
1593 | st->cur_skb = st->cur_skb->next; | ||
1594 | st->frag_idx = 0; | ||
1595 | goto next_skb; | ||
1596 | } else if (st->root_skb == st->cur_skb && | ||
1597 | skb_shinfo(st->root_skb)->frag_list) { | ||
1598 | st->cur_skb = skb_shinfo(st->root_skb)->frag_list; | ||
1599 | goto next_skb; | ||
1600 | } | ||
1601 | |||
1602 | return 0; | ||
1603 | } | ||
1604 | |||
1605 | /** | ||
1606 | * skb_abort_seq_read - Abort a sequential read of skb data | ||
1607 | * @st: state variable | ||
1608 | * | ||
1609 | * Must be called if skb_seq_read() was not called until it | ||
1610 | * returned 0. | ||
1611 | */ | ||
1612 | void skb_abort_seq_read(struct skb_seq_state *st) | ||
1613 | { | ||
1614 | if (st->frag_data) | ||
1615 | kunmap_skb_frag(st->frag_data); | ||
1616 | } | ||
1617 | |||
1618 | #define TS_SKB_CB(state) ((struct skb_seq_state *) &((state)->cb)) | ||
1619 | |||
1620 | static unsigned int skb_ts_get_next_block(unsigned int offset, const u8 **text, | ||
1621 | struct ts_config *conf, | ||
1622 | struct ts_state *state) | ||
1623 | { | ||
1624 | return skb_seq_read(offset, text, TS_SKB_CB(state)); | ||
1625 | } | ||
1626 | |||
1627 | static void skb_ts_finish(struct ts_config *conf, struct ts_state *state) | ||
1628 | { | ||
1629 | skb_abort_seq_read(TS_SKB_CB(state)); | ||
1630 | } | ||
1631 | |||
1632 | /** | ||
1633 | * skb_find_text - Find a text pattern in skb data | ||
1634 | * @skb: the buffer to look in | ||
1635 | * @from: search offset | ||
1636 | * @to: search limit | ||
1637 | * @config: textsearch configuration | ||
1638 | * @state: uninitialized textsearch state variable | ||
1639 | * | ||
1640 | * Finds a pattern in the skb data according to the specified | ||
1641 | * textsearch configuration. Use textsearch_next() to retrieve | ||
1642 | * subsequent occurrences of the pattern. Returns the offset | ||
1643 | * to the first occurrence or UINT_MAX if no match was found. | ||
1644 | */ | ||
1645 | unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, | ||
1646 | unsigned int to, struct ts_config *config, | ||
1647 | struct ts_state *state) | ||
1648 | { | ||
1649 | config->get_next_block = skb_ts_get_next_block; | ||
1650 | config->finish = skb_ts_finish; | ||
1651 | |||
1652 | skb_prepare_seq_read(skb, from, to, TS_SKB_CB(state)); | ||
1653 | |||
1654 | return textsearch_find(config, state); | ||
1655 | } | ||
1656 | |||
1503 | void __init skb_init(void) | 1657 | void __init skb_init(void) |
1504 | { | 1658 | { |
1505 | skbuff_head_cache = kmem_cache_create("skbuff_head_cache", | 1659 | skbuff_head_cache = kmem_cache_create("skbuff_head_cache", |
@@ -1538,3 +1692,7 @@ EXPORT_SYMBOL(skb_queue_tail); | |||
1538 | EXPORT_SYMBOL(skb_unlink); | 1692 | EXPORT_SYMBOL(skb_unlink); |
1539 | EXPORT_SYMBOL(skb_append); | 1693 | EXPORT_SYMBOL(skb_append); |
1540 | EXPORT_SYMBOL(skb_split); | 1694 | EXPORT_SYMBOL(skb_split); |
1695 | EXPORT_SYMBOL(skb_prepare_seq_read); | ||
1696 | EXPORT_SYMBOL(skb_seq_read); | ||
1697 | EXPORT_SYMBOL(skb_abort_seq_read); | ||
1698 | EXPORT_SYMBOL(skb_find_text); | ||
diff --git a/net/core/sock.c b/net/core/sock.c index a6ec3ada7f..12f6d9a2a5 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -206,13 +206,14 @@ int sock_setsockopt(struct socket *sock, int level, int optname, | |||
206 | */ | 206 | */ |
207 | 207 | ||
208 | #ifdef SO_DONTLINGER /* Compatibility item... */ | 208 | #ifdef SO_DONTLINGER /* Compatibility item... */ |
209 | switch (optname) { | 209 | if (optname == SO_DONTLINGER) { |
210 | case SO_DONTLINGER: | 210 | lock_sock(sk); |
211 | sock_reset_flag(sk, SOCK_LINGER); | 211 | sock_reset_flag(sk, SOCK_LINGER); |
212 | return 0; | 212 | release_sock(sk); |
213 | return 0; | ||
213 | } | 214 | } |
214 | #endif | 215 | #endif |
215 | 216 | ||
216 | if(optlen<sizeof(int)) | 217 | if(optlen<sizeof(int)) |
217 | return(-EINVAL); | 218 | return(-EINVAL); |
218 | 219 | ||
@@ -622,7 +623,8 @@ lenout: | |||
622 | * @prot: struct proto associated with this new sock instance | 623 | * @prot: struct proto associated with this new sock instance |
623 | * @zero_it: if we should zero the newly allocated sock | 624 | * @zero_it: if we should zero the newly allocated sock |
624 | */ | 625 | */ |
625 | struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) | 626 | struct sock *sk_alloc(int family, unsigned int __nocast priority, |
627 | struct proto *prot, int zero_it) | ||
626 | { | 628 | { |
627 | struct sock *sk = NULL; | 629 | struct sock *sk = NULL; |
628 | kmem_cache_t *slab = prot->slab; | 630 | kmem_cache_t *slab = prot->slab; |
@@ -750,7 +752,8 @@ unsigned long sock_i_ino(struct sock *sk) | |||
750 | /* | 752 | /* |
751 | * Allocate a skb from the socket's send buffer. | 753 | * Allocate a skb from the socket's send buffer. |
752 | */ | 754 | */ |
753 | struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int priority) | 755 | struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, |
756 | unsigned int __nocast priority) | ||
754 | { | 757 | { |
755 | if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { | 758 | if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { |
756 | struct sk_buff * skb = alloc_skb(size, priority); | 759 | struct sk_buff * skb = alloc_skb(size, priority); |
@@ -765,7 +768,8 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int | |||
765 | /* | 768 | /* |
766 | * Allocate a skb from the socket's receive buffer. | 769 | * Allocate a skb from the socket's receive buffer. |
767 | */ | 770 | */ |
768 | struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority) | 771 | struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, |
772 | unsigned int __nocast priority) | ||
769 | { | 773 | { |
770 | if (force || atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf) { | 774 | if (force || atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf) { |
771 | struct sk_buff *skb = alloc_skb(size, priority); | 775 | struct sk_buff *skb = alloc_skb(size, priority); |
@@ -780,7 +784,7 @@ struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int | |||
780 | /* | 784 | /* |
781 | * Allocate a memory block from the socket's option memory buffer. | 785 | * Allocate a memory block from the socket's option memory buffer. |
782 | */ | 786 | */ |
783 | void *sock_kmalloc(struct sock *sk, int size, int priority) | 787 | void *sock_kmalloc(struct sock *sk, int size, unsigned int __nocast priority) |
784 | { | 788 | { |
785 | if ((unsigned)size <= sysctl_optmem_max && | 789 | if ((unsigned)size <= sysctl_optmem_max && |
786 | atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) { | 790 | atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) { |
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index c8be646cb1..8f817ad9f5 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c | |||
@@ -13,12 +13,8 @@ | |||
13 | #ifdef CONFIG_SYSCTL | 13 | #ifdef CONFIG_SYSCTL |
14 | 14 | ||
15 | extern int netdev_max_backlog; | 15 | extern int netdev_max_backlog; |
16 | extern int netdev_budget; | ||
16 | extern int weight_p; | 17 | extern int weight_p; |
17 | extern int no_cong_thresh; | ||
18 | extern int no_cong; | ||
19 | extern int lo_cong; | ||
20 | extern int mod_cong; | ||
21 | extern int netdev_fastroute; | ||
22 | extern int net_msg_cost; | 18 | extern int net_msg_cost; |
23 | extern int net_msg_burst; | 19 | extern int net_msg_burst; |
24 | 20 | ||
@@ -35,19 +31,6 @@ extern int sysctl_somaxconn; | |||
35 | extern char sysctl_divert_version[]; | 31 | extern char sysctl_divert_version[]; |
36 | #endif /* CONFIG_NET_DIVERT */ | 32 | #endif /* CONFIG_NET_DIVERT */ |
37 | 33 | ||
38 | /* | ||
39 | * This strdup() is used for creating copies of network | ||
40 | * device names to be handed over to sysctl. | ||
41 | */ | ||
42 | |||
43 | char *net_sysctl_strdup(const char *s) | ||
44 | { | ||
45 | char *rv = kmalloc(strlen(s)+1, GFP_KERNEL); | ||
46 | if (rv) | ||
47 | strcpy(rv, s); | ||
48 | return rv; | ||
49 | } | ||
50 | |||
51 | ctl_table core_table[] = { | 34 | ctl_table core_table[] = { |
52 | #ifdef CONFIG_NET | 35 | #ifdef CONFIG_NET |
53 | { | 36 | { |
@@ -99,38 +82,6 @@ ctl_table core_table[] = { | |||
99 | .proc_handler = &proc_dointvec | 82 | .proc_handler = &proc_dointvec |
100 | }, | 83 | }, |
101 | { | 84 | { |
102 | .ctl_name = NET_CORE_NO_CONG_THRESH, | ||
103 | .procname = "no_cong_thresh", | ||
104 | .data = &no_cong_thresh, | ||
105 | .maxlen = sizeof(int), | ||
106 | .mode = 0644, | ||
107 | .proc_handler = &proc_dointvec | ||
108 | }, | ||
109 | { | ||
110 | .ctl_name = NET_CORE_NO_CONG, | ||
111 | .procname = "no_cong", | ||
112 | .data = &no_cong, | ||
113 | .maxlen = sizeof(int), | ||
114 | .mode = 0644, | ||
115 | .proc_handler = &proc_dointvec | ||
116 | }, | ||
117 | { | ||
118 | .ctl_name = NET_CORE_LO_CONG, | ||
119 | .procname = "lo_cong", | ||
120 | .data = &lo_cong, | ||
121 | .maxlen = sizeof(int), | ||
122 | .mode = 0644, | ||
123 | .proc_handler = &proc_dointvec | ||
124 | }, | ||
125 | { | ||
126 | .ctl_name = NET_CORE_MOD_CONG, | ||
127 | .procname = "mod_cong", | ||
128 | .data = &mod_cong, | ||
129 | .maxlen = sizeof(int), | ||
130 | .mode = 0644, | ||
131 | .proc_handler = &proc_dointvec | ||
132 | }, | ||
133 | { | ||
134 | .ctl_name = NET_CORE_MSG_COST, | 85 | .ctl_name = NET_CORE_MSG_COST, |
135 | .procname = "message_cost", | 86 | .procname = "message_cost", |
136 | .data = &net_msg_cost, | 87 | .data = &net_msg_cost, |
@@ -174,9 +125,15 @@ ctl_table core_table[] = { | |||
174 | .mode = 0644, | 125 | .mode = 0644, |
175 | .proc_handler = &proc_dointvec | 126 | .proc_handler = &proc_dointvec |
176 | }, | 127 | }, |
128 | { | ||
129 | .ctl_name = NET_CORE_BUDGET, | ||
130 | .procname = "netdev_budget", | ||
131 | .data = &netdev_budget, | ||
132 | .maxlen = sizeof(int), | ||
133 | .mode = 0644, | ||
134 | .proc_handler = &proc_dointvec | ||
135 | }, | ||
177 | { .ctl_name = 0 } | 136 | { .ctl_name = 0 } |
178 | }; | 137 | }; |
179 | 138 | ||
180 | EXPORT_SYMBOL(net_sysctl_strdup); | ||
181 | |||
182 | #endif | 139 | #endif |
diff --git a/net/core/utils.c b/net/core/utils.c index e11a8654f3..88eb8b68e2 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
@@ -23,10 +23,10 @@ | |||
23 | #include <linux/percpu.h> | 23 | #include <linux/percpu.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | 25 | ||
26 | #include <asm/byteorder.h> | ||
26 | #include <asm/system.h> | 27 | #include <asm/system.h> |
27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
28 | 29 | ||
29 | |||
30 | /* | 30 | /* |
31 | This is a maximally equidistributed combined Tausworthe generator | 31 | This is a maximally equidistributed combined Tausworthe generator |
32 | based on code from GNU Scientific Library 1.5 (30 Jun 2004) | 32 | based on code from GNU Scientific Library 1.5 (30 Jun 2004) |
@@ -153,3 +153,38 @@ int net_ratelimit(void) | |||
153 | EXPORT_SYMBOL(net_random); | 153 | EXPORT_SYMBOL(net_random); |
154 | EXPORT_SYMBOL(net_ratelimit); | 154 | EXPORT_SYMBOL(net_ratelimit); |
155 | EXPORT_SYMBOL(net_srandom); | 155 | EXPORT_SYMBOL(net_srandom); |
156 | |||
157 | /* | ||
158 | * Convert an ASCII string to binary IP. | ||
159 | * This is outside of net/ipv4/ because various code that uses IP addresses | ||
160 | * is otherwise not dependent on the TCP/IP stack. | ||
161 | */ | ||
162 | |||
163 | __u32 in_aton(const char *str) | ||
164 | { | ||
165 | unsigned long l; | ||
166 | unsigned int val; | ||
167 | int i; | ||
168 | |||
169 | l = 0; | ||
170 | for (i = 0; i < 4; i++) | ||
171 | { | ||
172 | l <<= 8; | ||
173 | if (*str != '\0') | ||
174 | { | ||
175 | val = 0; | ||
176 | while (*str != '\0' && *str != '.') | ||
177 | { | ||
178 | val *= 10; | ||
179 | val += *str - '0'; | ||
180 | str++; | ||
181 | } | ||
182 | l |= val; | ||
183 | if (*str != '\0') | ||
184 | str++; | ||
185 | } | ||
186 | } | ||
187 | return(htonl(l)); | ||
188 | } | ||
189 | |||
190 | EXPORT_SYMBOL(in_aton); | ||
diff --git a/net/core/wireless.c b/net/core/wireless.c index b2fe378dfb..3ff5639c0b 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c | |||
@@ -1102,6 +1102,7 @@ static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb, | |||
1102 | nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r)); | 1102 | nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r)); |
1103 | r = NLMSG_DATA(nlh); | 1103 | r = NLMSG_DATA(nlh); |
1104 | r->ifi_family = AF_UNSPEC; | 1104 | r->ifi_family = AF_UNSPEC; |
1105 | r->__ifi_pad = 0; | ||
1105 | r->ifi_type = dev->type; | 1106 | r->ifi_type = dev->type; |
1106 | r->ifi_index = dev->ifindex; | 1107 | r->ifi_index = dev->ifindex; |
1107 | r->ifi_flags = dev->flags; | 1108 | r->ifi_flags = dev->flags; |