Commit f63dc6c8 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/sparc-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 941071f4 6e27cd69
......@@ -206,6 +206,8 @@ SHA256 algorithm contributors:
AES algorithm contributors:
Alexander Kjeldaas
Herbert Valerio Riedel
Kyle McMartin
Adam J. Richter
Please send any credits updates or corrections to:
......
......@@ -721,6 +721,23 @@ might come in, we attempt to re-add ourselves to the poll list.
APPENDIX 3: Scheduling issues.
==============================
As seen NAPI moves processing to softirq level. Linux uses the ksoftirqd as the
general solution to schedule softirq's to run before next interrupt and by putting
them under scheduler control. Also this prevents consecutive softirq's from
monopolize the CPU. This also have the effect that the priority of ksoftirq needs
to be considered when running very CPU-intensive applications and networking to
get the proper balance of softirq/user balance. Increasing ksoftirq priority to 0
(eventually more) is reported cure problems with low network performance at high
CPU load.
Most used processes in a GIGE router:
USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND
root 3 0.2 0.0 0 0 ? RWN Aug 15 602:00 (ksoftirqd_CPU0)
root 232 0.0 7.9 41400 40884 ? S Aug 15 74:12 gated
--------------------------------------------------------------------
relevant sites:
......
......@@ -6,12 +6,14 @@ menu "Cryptographic options"
config CRYPTO
bool "Cryptographic API"
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m
help
This option provides the core Cryptographic API.
config CRYPTO_HMAC
bool "HMAC support"
depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m
help
HMAC: Keyed-Hashing for Message Authentication (RFC2104).
This is required for IPSec.
......@@ -31,12 +33,14 @@ config CRYPTO_MD4
config CRYPTO_MD5
tristate "MD5 digest algorithm"
depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m
help
MD5 message digest algorithm (RFC1321).
config CRYPTO_SHA1
tristate "SHA1 digest algorithm"
depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m
help
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
......@@ -52,6 +56,7 @@ config CRYPTO_SHA256
config CRYPTO_DES
tristate "DES and Triple DES EDE cipher algorithms"
depends on CRYPTO
default y if INET_AH=y || INET_AH=m || INET_ESP=y || INET_ESP=m
help
DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
......
......@@ -7,6 +7,8 @@
*
* Linux developers:
* Alexander Kjeldaas <astor@fast.no>
* Herbert Valerio Riedel <hvr@hvrlab.org>
* Kyle McMartin <kyle@debian.org>
* Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
*
* This program is free software; you can redistribute it and/or modify
......
......@@ -497,6 +497,7 @@ int kernel_read(struct file *file, unsigned long offset,
static int exec_mmap(struct mm_struct *mm)
{
struct task_struct *tsk;
struct mm_struct * old_mm, *active_mm;
/* Add it to the list of mm's */
......@@ -505,14 +506,17 @@ static int exec_mmap(struct mm_struct *mm)
mmlist_nr++;
spin_unlock(&mmlist_lock);
task_lock(current);
/* Notify parent that we're no longer interested in the old VM */
tsk = current;
old_mm = current->mm;
active_mm = current->active_mm;
current->mm = mm;
current->active_mm = mm;
mm_release(tsk, old_mm);
task_lock(tsk);
active_mm = tsk->active_mm;
tsk->mm = mm;
tsk->active_mm = mm;
activate_mm(active_mm, mm);
task_unlock(current);
mm_release();
task_unlock(tsk);
if (old_mm) {
if (active_mm != old_mm) BUG();
mmput(old_mm);
......
......@@ -209,6 +209,8 @@ ev4_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
tbiap();
}
#define deactivate_mm(tsk,mm) do { } while (0)
#ifdef CONFIG_ALPHA_GENERIC
# define switch_mm(a,b,c,d) alpha_mv.mv_switch_mm((a),(b),(c),(d))
# define activate_mm(x,y) alpha_mv.mv_activate_mm((x),(y))
......
......@@ -47,6 +47,8 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
}
}
#define deactivate_mm(tsk,mm) do { } while (0)
static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
{
cpu_switch_mm(next->pgd, next);
......
......@@ -7,6 +7,8 @@ extern void destroy_context(struct mm_struct *mm);
extern void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk, int cpu);
#define deactivate_mm(tsk,mm) do { } while (0)
#define activate_mm(prev,next) switch_mm((prev),(next),NULL,smp_processor_id())
/* current active pgd - this is similar to other processors pgd
......
......@@ -62,6 +62,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, str
#endif
}
#define deactivate_mm(tsk, mm) \
asm("movl %0,%%fs ; movl %0,%%gs": :"r" (0))
#define activate_mm(prev, next) \
switch_mm((prev),(next),NULL,smp_processor_id())
......
......@@ -143,6 +143,8 @@ activate_context (struct mm_struct *mm)
} while (unlikely(context != mm->context));
}
#define deactivate_mm(tsk,mm) do { } while (0)
/*
* Switch from address space PREV to address space NEXT.
*/
......
......@@ -89,6 +89,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, str
}
}
#define deactivate_mm(tsk,mm) do { } while (0)
extern inline void activate_mm(struct mm_struct *prev_mm,
struct mm_struct *next_mm)
{
......
......@@ -23,6 +23,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, str
{
}
#define deactivate_mm(tsk,mm) do { } while (0)
extern inline void activate_mm(struct mm_struct *prev_mm,
struct mm_struct *next_mm)
{
......
......@@ -98,6 +98,8 @@ extern inline void destroy_context(struct mm_struct *mm)
/* Nothing to do. */
}
#define deactivate_mm(tsk,mm) do { } while (0)
/*
* After we have set current->mm to a new value, this activates
* the context for the new mm so we see the new mappings.
......
......@@ -111,6 +111,8 @@ extern inline void destroy_context(struct mm_struct *mm)
#endif
}
#define deactivate_mm(tsk,mm) do { } while (0)
/*
* After we have set current->mm to a new value, this activates
* the context for the new mm so we see the new mappings.
......
......@@ -52,6 +52,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, str
}
}
#define deactivate_mm(tsk,mm) do { } while (0)
static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
{
/*
......
......@@ -160,6 +160,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
set_context(next->context, next->pgd);
}
#define deactivate_mm(tsk,mm) do { } while (0)
/*
* After we have set current->mm to a new value, this activates
* the context for the new mm so we see the new mappings.
......
......@@ -146,6 +146,8 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
set_bit(cpu, &next->cpu_vm_mask);
}
#define deactivate_mm(tsk,mm) do { } while (0)
/*
* After we have set current->mm to a new value, this activates
* the context for the new mm so we see the new mappings.
......
......@@ -37,6 +37,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
set_bit(cpu, &next->cpu_vm_mask);
}
#define deactivate_mm(tsk,mm) do { } while (0)
extern inline void activate_mm(struct mm_struct *prev,
struct mm_struct *next)
{
......
......@@ -36,6 +36,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
set_bit(cpu, &next->cpu_vm_mask);
}
#define deactivate_mm(tsk,mm) do { } while (0)
extern inline void activate_mm(struct mm_struct *prev,
struct mm_struct *next)
{
......
......@@ -178,6 +178,8 @@ static __inline__ void switch_mm(struct mm_struct *prev,
}
}
#define deactivate_mm(tsk,mm) do { } while (0)
#define activate_mm(prev, next) \
switch_mm((prev),(next),NULL,smp_processor_id())
......
......@@ -30,6 +30,8 @@ BTFIXUPDEF_CALL(void, switch_mm, struct mm_struct *, struct mm_struct *, struct
#define switch_mm(old_mm, mm, tsk, cpu) BTFIXUP_CALL(switch_mm)(old_mm, mm, tsk, cpu)
#define deactivate_mm(tsk,mm) do { } while (0)
/* Activate a new MM instance for the current task. */
#define activate_mm(active_mm, mm) switch_mm((active_mm), (mm), NULL, smp_processor_id())
......
......@@ -143,6 +143,8 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
extern void __flush_tlb_mm(unsigned long, unsigned long);
#define deactivate_mm(tsk,mm) do { } while (0)
/* Activate a new MM instance for the current task. */
static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm)
{
......
......@@ -12,6 +12,8 @@
#define get_mmu_context(task) do ; while(0)
#define activate_context(tsk) do ; while(0)
#define deactivate_mm(tsk,mm) do { } while (0)
static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
{
}
......
......@@ -4,6 +4,7 @@
#define destroy_context(mm) ((void)0)
#define init_new_context(tsk,mm) 0
#define switch_mm(prev,next,tsk,cpu) ((void)0)
#define deactivate_mm(tsk,mm) do { } while (0)
#define activate_mm(prev,next) ((void)0)
#define enter_lazy_tlb(mm,tsk,cpu) ((void)0)
......
......@@ -62,6 +62,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
#endif
}
#define deactivate_mm(tsk,mm) do { } while (0)
#define activate_mm(prev, next) \
switch_mm((prev),(next),NULL,smp_processor_id())
......
......@@ -50,6 +50,13 @@ extern int ip_nat_mangle_tcp_packet(struct sk_buff **skb,
unsigned int match_len,
char *rep_buffer,
unsigned int rep_len);
extern int ip_nat_mangle_udp_packet(struct sk_buff **skb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
unsigned int match_len,
char *rep_buffer,
unsigned int rep_len);
extern int ip_nat_seq_adjust(struct sk_buff *skb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo);
......
......@@ -566,7 +566,7 @@ static inline void mmdrop(struct mm_struct * mm)
/* mmput gets rid of the mappings and all user-space */
extern void mmput(struct mm_struct *);
/* Remove the current tasks stale references to the old mm_struct */
extern void mm_release(void);
extern void mm_release(struct task_struct *, struct mm_struct *);
extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
extern void flush_thread(void);
......
......@@ -419,7 +419,7 @@ static inline void __exit_mm(struct task_struct * tsk)
{
struct mm_struct *mm = tsk->mm;
mm_release();
mm_release(tsk, mm);
if (!mm)
return;
/*
......
......@@ -399,17 +399,19 @@ void mmput(struct mm_struct *mm)
* restoring the old one. . .
* Eric Biederman 10 January 1998
*/
void mm_release(void)
void mm_release(struct task_struct *tsk, struct mm_struct *mm)
{
struct task_struct *tsk = current;
struct completion *vfork_done = tsk->vfork_done;
/* Get rid of any cached register state */
deactivate_mm(tsk, mm);
/* notify parent sleeping on vfork() */
if (vfork_done) {
tsk->vfork_done = NULL;
complete(vfork_done);
}
if (tsk->clear_child_tid) {
if (tsk->clear_child_tid && atomic_read(&mm->mm_users) > 1) {
int * tidptr = tsk->clear_child_tid;
tsk->clear_child_tid = NULL;
......
......@@ -967,22 +967,27 @@ int ip_conntrack_expect_related(struct ip_conntrack *related_to,
related_to->expecting >= related_to->helper->max_expected) {
struct list_head *cur_item;
/* old == NULL */
if (!(related_to->helper->flags &
IP_CT_HELPER_F_REUSE_EXPECT)) {
WRITE_UNLOCK(&ip_conntrack_lock);
if (net_ratelimit())
printk(KERN_WARNING
"ip_conntrack: max number of expected "
"connections %i of %s reached for "
"%u.%u.%u.%u->%u.%u.%u.%u%s\n",
"%u.%u.%u.%u->%u.%u.%u.%u\n",
related_to->helper->max_expected,
related_to->helper->name,
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip),
related_to->helper->flags & IP_CT_HELPER_F_REUSE_EXPECT ?
", reusing" : "");
if (!(related_to->helper->flags &
IP_CT_HELPER_F_REUSE_EXPECT)) {
WRITE_UNLOCK(&ip_conntrack_lock);
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip));
return -EPERM;
}
DEBUGP("ip_conntrack: max number of expected "
"connections %i of %s reached for "
"%u.%u.%u.%u->%u.%u.%u.%u, reusing\n",
related_to->helper->max_expected,
related_to->helper->name,
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip),
NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip));
/* choose the the oldest expectation to evict */
list_for_each(cur_item, &related_to->sibling_list) {
......
......@@ -200,7 +200,7 @@ static int find_pattern(const char *data, size_t dlen,
DEBUGP("ftp: string mismatch\n");
for (i = 0; i < plen; i++) {
DEBUGFTP("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
DEBUGP("ftp:char %u `%c'(%u) vs `%c'(%u)\n",
i, data[i], data[i],
pattern[i], pattern[i]);
}
......
......@@ -186,13 +186,13 @@ static int tcp_packet(struct ip_conntrack *conntrack,
&& tcph->syn && tcph->ack)
conntrack->proto.tcp.handshake_ack
= htonl(ntohl(tcph->seq) + 1);
WRITE_UNLOCK(&tcp_lock);
/* If only reply is a RST, we can consider ourselves not to
have an established connection: this is a fairly common
problem case, so we can delete the conntrack
immediately. --RR */
if (!(conntrack->status & IPS_SEEN_REPLY) && tcph->rst) {
WRITE_UNLOCK(&tcp_lock);
if (del_timer(&conntrack->timeout))
conntrack->timeout.function((unsigned long)conntrack);
} else {
......@@ -203,6 +203,7 @@ static int tcp_packet(struct ip_conntrack *conntrack,
&& tcph->ack_seq == conntrack->proto.tcp.handshake_ack)
set_bit(IPS_ASSURED_BIT, &conntrack->status);
WRITE_UNLOCK(&tcp_lock);
ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]);
}
......
......@@ -8,6 +8,9 @@
* - add support for SACK adjustment
* 14 Mar 2002 Harald Welte <laforge@gnumonks.org>:
* - merge SACK support into newnat API
* 16 Aug 2002 Brian J. Murrell <netfilter@interlinx.bc.ca>:
* - make ip_nat_resize_packet more generic (TCP and UDP)
* - add ip_nat_mangle_udp_packet
*/
#include <linux/version.h>
#include <linux/config.h>
......@@ -22,6 +25,7 @@
#include <net/icmp.h>
#include <net/ip.h>
#include <net/tcp.h>
#include <net/udp.h>
#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
......@@ -51,18 +55,12 @@ ip_nat_resize_packet(struct sk_buff **skb,
int new_size)
{
struct iphdr *iph;
struct tcphdr *tcph;
void *data;
int dir;
struct ip_nat_seq *this_way, *other_way;
DEBUGP("ip_nat_resize_packet: old_size = %u, new_size = %u\n",
(*skb)->len, new_size);
iph = (*skb)->nh.iph;
tcph = (void *)iph + iph->ihl*4;
data = (void *)tcph + tcph->doff*4;
dir = CTINFO2DIR(ctinfo);
this_way = &ct->nat.info.seq[dir];
......@@ -84,8 +82,9 @@ ip_nat_resize_packet(struct sk_buff **skb,
}
iph = (*skb)->nh.iph;
tcph = (void *)iph + iph->ihl*4;
data = (void *)tcph + tcph->doff*4;
if (iph->protocol == IPPROTO_TCP) {
struct tcphdr *tcph = (void *)iph + iph->ihl*4;
void *data = (void *)tcph + tcph->doff*4;
DEBUGP("ip_nat_resize_packet: Seq_offset before: ");
DUMP_OFFSET(this_way);
......@@ -101,20 +100,23 @@ ip_nat_resize_packet(struct sk_buff **skb,
this_way->correction_pos = ntohl(tcph->seq);
this_way->offset_before = this_way->offset_after;
this_way->offset_after = (int32_t)
this_way->offset_before + new_size - (*skb)->len;
this_way->offset_before + new_size -
(*skb)->len;
}
UNLOCK_BH(&ip_nat_seqofs_lock);
DEBUGP("ip_nat_resize_packet: Seq_offset after: ");
DUMP_OFFSET(this_way);
}
return 1;
}
/* Generic function for mangling variable-length address changes inside
* NATed connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX command in FTP).
* NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX
* command in FTP).
*
* Takes care about all the nasty sequence number changes, checksumming,
* skb enlargement, ...
......@@ -174,6 +176,7 @@ ip_nat_mangle_tcp_packet(struct sk_buff **skb,
tcph = (void *)iph + iph->ihl*4;
data = (void *)tcph + tcph->doff*4;
if (rep_len != match_len)
/* move post-replacement */
memmove(data + match_offset + rep_len,
data + match_offset + match_len,
......@@ -208,6 +211,114 @@ ip_nat_mangle_tcp_packet(struct sk_buff **skb,
return 1;
}
/* Generic function for mangling variable-length address changes inside
* NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
* command in the Amanda protocol)
*
* Takes care about all the nasty sequence number changes, checksumming,
* skb enlargement, ...
*
* XXX - This function could be merged with ip_nat_mangle_tcp_packet which
* should be fairly easy to do.
*/
int
ip_nat_mangle_udp_packet(struct sk_buff **skb,
struct ip_conntrack *ct,
enum ip_conntrack_info ctinfo,
unsigned int match_offset,
unsigned int match_len,
char *rep_buffer,
unsigned int rep_len)
{
struct iphdr *iph = (*skb)->nh.iph;
struct udphdr *udph = (void *)iph + iph->ihl * 4;
unsigned char *data;
u_int32_t udplen, newlen, newudplen;
udplen = (*skb)->len - iph->ihl*4;
newudplen = udplen - match_len + rep_len;
newlen = iph->ihl*4 + newudplen;
if (newlen > 65535) {
if (net_ratelimit())
printk("ip_nat_mangle_udp_packet: nat'ed packet "
"exceeds maximum packet size\n");
return 0;
}
if ((*skb)->len != newlen) {
if (!ip_nat_resize_packet(skb, ct, ctinfo, newlen)) {
printk("resize_packet failed!!\n");
return 0;
}
}
/* Alexey says: if a hook changes _data_ ... it can break
original packet sitting in tcp queue and this is fatal */
if (skb_cloned(*skb)) {
struct sk_buff *nskb = skb_copy(*skb, GFP_ATOMIC);
if (!nskb) {
if (net_ratelimit())
printk("Out of memory cloning TCP packet\n");
return 0;
}
/* Rest of kernel will get very unhappy if we pass it
a suddenly-orphaned skbuff */
if ((*skb)->sk)
skb_set_owner_w(nskb, (*skb)->sk);
kfree_skb(*skb);
*skb = nskb;
}
/* skb may be copied !! */
iph = (*skb)->nh.iph;
udph = (void *)iph + iph->ihl*4;
data = (void *)udph + sizeof(struct udphdr);
if (rep_len != match_len)
/* move post-replacement */
memmove(data + match_offset + rep_len,
data + match_offset + match_len,
(*skb)->tail - (data + match_offset + match_len));
/* insert data from buffer */
memcpy(data + match_offset, rep_buffer, rep_len);
/* update skb info */
if (newlen > (*skb)->len) {
DEBUGP("ip_nat_mangle_udp_packet: Extending packet by "
"%u to %u bytes\n", newlen - (*skb)->len, newlen);
skb_put(*skb, newlen - (*skb)->len);
} else {
DEBUGP("ip_nat_mangle_udp_packet: Shrinking packet from "
"%u to %u bytes\n", (*skb)->len, newlen);
skb_trim(*skb, newlen);
}
/* update the length of the UDP and IP packets to the new values*/
udph->len = htons((*skb)->len - iph->ihl*4);
iph->tot_len = htons(newlen);
/* fix udp checksum if udp checksum was previously calculated */
if ((*skb)->csum != 0) {
(*skb)->csum = csum_partial((char *)udph +
sizeof(struct udphdr),
newudplen - sizeof(struct udphdr),
0);
udph->check = 0;
udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
newudplen, IPPROTO_UDP,
csum_partial((char *)udph,
sizeof(struct udphdr),
(*skb)->csum));
}
ip_send_check(iph);
return 1;
}
/* Adjust one found SACK option including checksum correction */
static void
sack_adjust(struct tcphdr *tcph,
......
......@@ -359,5 +359,6 @@ EXPORT_SYMBOL(ip_nat_helper_register);
EXPORT_SYMBOL(ip_nat_helper_unregister);
EXPORT_SYMBOL(ip_nat_cheat_check);
EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
EXPORT_SYMBOL(ip_nat_used_tuple);
MODULE_LICENSE("GPL");
......@@ -88,8 +88,8 @@ set_ect_tcp(struct sk_buff **pskb, struct iphdr *iph,
}
if (diffs[0] != *tcpflags) {
diffs[0] = htons(diffs[0]) ^ 0xFFFF;
diffs[1] = htons(*tcpflags);
diffs[0] = diffs[0] ^ 0xFFFF;
diffs[1] = *tcpflags;
tcph->check = csum_fold(csum_partial((char *)diffs,
sizeof(diffs),
tcph->check^0xFFFF));
......
......@@ -6,6 +6,8 @@
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/icmp.h>
#include <net/icmp.h>
#include <net/ip.h>
#include <net/tcp.h>
......@@ -164,6 +166,7 @@ static void send_reset(struct sk_buff *oldskb, int local)
static void send_unreach(struct sk_buff *skb_in, int code)
{
struct iphdr *iph;
struct udphdr *udph;
struct icmphdr *icmph;
struct sk_buff *nskb;
u32 saddr;
......@@ -193,6 +196,19 @@ static void send_unreach(struct sk_buff *skb_in, int code)
if (iph->frag_off&htons(IP_OFFSET))
return;
/* if UDP checksum is set, verify it's correct */
if (iph->protocol == IPPROTO_UDP
&& skb_in->tail-(u8*)iph >= sizeof(struct udphdr)) {
int datalen = skb_in->len - (iph->ihl<<2);
udph = (struct udphdr *)((char *)iph + (iph->ihl<<2));
if (udph->check
&& csum_tcpudp_magic(iph->saddr, iph->daddr,
datalen, IPPROTO_UDP,
csum_partial((char *)udph, datalen,
0)) != 0)
return;
}
/* If we send an ICMP error to an ICMP error a mess would result.. */
if (iph->protocol == IPPROTO_ICMP
&& skb_in->tail-(u8*)iph >= sizeof(struct icmphdr)) {
......
......@@ -12,6 +12,7 @@
* module loadtime -HW
* 2002/07/07 remove broken nflog_rcv() function -HW
* 2002/08/29 fix shifted/unshifted nlgroup bug -HW
* 2002/10/30 fix uninitialized mac_len field - <Anders K. Pedersen>
*
* Released under the terms of the GPL
*
......@@ -31,7 +32,7 @@
* Specify, after how many clock ticks (intel: 100 per second) the queue
* should be flushed even if it is not full yet.
*
* ipt_ULOG.c,v 1.21 2002/08/29 10:54:34 laforge Exp
* ipt_ULOG.c,v 1.22 2002/10/30 09:07:31 laforge Exp
*/
#include <linux/module.h>
......@@ -224,7 +225,8 @@ static unsigned int ipt_ulog_target(struct sk_buff **pskb,
&& in->hard_header_len <= ULOG_MAC_LEN) {
memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len);
pm->mac_len = in->hard_header_len;
}
} else
pm->mac_len = 0;
if (in)
strncpy(pm->indev_name, in->name, sizeof(pm->indev_name));
......
......@@ -78,7 +78,7 @@ checkentry(const char *tablename,
/* Must specify proto == TCP/UDP, no unknown flags or bad count */
return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP)
&& !(ip->flags & IPT_INV_PROTO)
&& !(ip->invflags & IPT_INV_PROTO)
&& matchsize == IPT_ALIGN(sizeof(struct ipt_multiport))
&& (multiinfo->flags == IPT_MULTIPORT_SOURCE
|| multiinfo->flags == IPT_MULTIPORT_DESTINATION
......
......@@ -310,6 +310,7 @@ struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx)
*/
void xfrm_probe_algs(void)
{
#ifdef CONFIG_CRYPTO
int i, status;
BUG_ON(in_softirq());
......@@ -325,6 +326,7 @@ void xfrm_probe_algs(void)
if (ealg_list[i].available != status)
ealg_list[i].available = status;
}
#endif
}
int xfrm_count_auth_supported(void)
......
......@@ -684,7 +684,7 @@ static int __init init_ipv6_mibs(void)
}
static void __exit cleanup_ipv6_mibs(void)
static void cleanup_ipv6_mibs(void)
{
kfree_percpu(ipv6_statistics[0]);
kfree_percpu(ipv6_statistics[1]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment