--- linux/net/ipv4/sysctl_net_ipv4.c 2008-12-13 17:56:16.000000000 -0600 +++ linux/net/ipv4/sysctl_net_ipv4.c 2008-12-17 13:57:26.000000000 -0600 @@ -28,6 +28,7 @@ static int ip_local_port_range_max[] = { extern seqlock_t sysctl_port_range_lock; extern int sysctl_local_port_range[2]; +extern int sysctl_raw_hdrincl_nomangle; /* Update system visible IP port range */ static void set_local_port_range(int range[2]) @@ -745,6 +746,14 @@ static struct ctl_table ipv4_table[] = { .strategy = &sysctl_intvec, .extra1 = &zero }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "raw_hdrincl_nomangle", + .data = &sysctl_raw_hdrincl_nomangle, + .maxlen = sizeof(sysctl_raw_hdrincl_nomangle), + .mode = 0644, + .proc_handler = &proc_dointvec + }, { .ctl_name = 0 } }; --- linux/net/ipv4/raw.c 2008-12-13 17:56:16.000000000 -0600 +++ linux/net/ipv4/raw.c 2008-12-16 20:42:20.000000000 -0600 @@ -82,6 +82,9 @@ static struct raw_hashinfo raw_v4_hashin .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), }; +int sysctl_raw_hdrincl_nomangle __read_mostly; +EXPORT_SYMBOL(sysctl_raw_hdrincl_nomangle); + void raw_hash_sk(struct sock *sk) { struct raw_hashinfo *h = sk->sk_prot->h.raw_hash; @@ -358,7 +361,8 @@ static int raw_send_hdrinc(struct sock * /* We don't modify invalid header */ iphlen = iph->ihl * 4; - if (iphlen >= sizeof(*iph) && iphlen <= length) { + if (iphlen >= sizeof(*iph) && iphlen <= length && + sysctl_raw_hdrincl_nomangle == 0) { if (!iph->saddr) iph->saddr = rt->rt_src; iph->check = 0;