summaryrefslogtreecommitdiff
path: root/net/ipv4
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-01-24 18:49:18 -0200
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-01-24 18:49:18 -0200
commita32f7d1ad3744914273c6907204c2ab3b5d496a0 (patch)
tree1c5ae321ee85665707177547c07810ff7e09e1ab /net/ipv4
parent6b9e50c463efc5c361496ae6a895cc966ff8025b (diff)
parent68d6f84ba0c47e658beff3a4bf0c43acee4b4690 (diff)
Merge branch 'v4l_for_linus' into staging/for_v3.9
* v4l_for_linus: (464 commits) [media] uvcvideo: Set error_idx properly for S_EXT_CTRLS failures [media] uvcvideo: Cleanup leftovers of partial revert [media] uvcvideo: Return -EACCES when trying to set a read-only control Linux 3.8-rc3 mm: reinstante dropped pmd_trans_splitting() check cred: Remove tgcred pointer from struct cred drm/ttm: fix fence locking in ttm_buffer_object_transfer ARM: clps711x: Fix bad merge of clockevents setup ARM: highbank: save and restore L2 cache and GIC on suspend ARM: highbank: add a power request clear ARM: highbank: fix secondary boot and hotplug ARM: highbank: fix typos with hignbank in power request functions ARM: dts: fix highbank cpu mpidr values ARM: dts: add device_type prop to cpu nodes on Calxeda platforms drm/prime: drop reference on imported dma-buf come from gem xen/netfront: improve truesize tracking ARM: mx5: Fix MX53 flexcan2 clock ARM: OMAP2+: am33xx-hwmod: Fix wrongly terminated am33xx_usbss_mpu_irqs array sctp: fix Kconfig bug in default cookie hmac selection EDAC: Cleanup device deregistering path ... Conflicts: drivers/media/pci/dm1105/dm1105.c drivers/media/platform/soc_camera/mx2_camera.c
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/arp.c10
-rw-r--r--net/ipv4/devinet.c2
-rw-r--r--net/ipv4/ip_gre.c13
-rw-r--r--net/ipv4/ipconfig.c8
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c1
-rw-r--r--net/ipv4/netfilter/iptable_nat.c15
-rw-r--r--net/ipv4/tcp_input.c14
7 files changed, 42 insertions, 21 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index ce6fbdfd40b8..9547a273b9e9 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -321,7 +321,7 @@ static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb)
static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
{
__be32 saddr = 0;
- u8 *dst_ha = NULL;
+ u8 dst_ha[MAX_ADDR_LEN], *dst_hw = NULL;
struct net_device *dev = neigh->dev;
__be32 target = *(__be32 *)neigh->primary_key;
int probes = atomic_read(&neigh->probes);
@@ -363,8 +363,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
if (probes < 0) {
if (!(neigh->nud_state & NUD_VALID))
pr_debug("trying to ucast probe in NUD_INVALID\n");
- dst_ha = neigh->ha;
- read_lock_bh(&neigh->lock);
+ neigh_ha_snapshot(dst_ha, neigh, dev);
+ dst_hw = dst_ha;
} else {
probes -= neigh->parms->app_probes;
if (probes < 0) {
@@ -376,9 +376,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
}
arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
- dst_ha, dev->dev_addr, NULL);
- if (dst_ha)
- read_unlock_bh(&neigh->lock);
+ dst_hw, dev->dev_addr, NULL);
}
static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index cc06a47f1216..a8e4f2665d5e 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -823,9 +823,9 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (!ifa) {
ret = -ENOBUFS;
ifa = inet_alloc_ifa();
- INIT_HLIST_NODE(&ifa->hash);
if (!ifa)
break;
+ INIT_HLIST_NODE(&ifa->hash);
if (colon)
memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
else
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index a85ae2f7a21c..303012adf9e6 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -750,6 +750,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
int gre_hlen;
__be32 dst;
int mtu;
+ u8 ttl;
if (skb->ip_summed == CHECKSUM_PARTIAL &&
skb_checksum_help(skb))
@@ -760,7 +761,10 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
gre_hlen = 0;
- tiph = (const struct iphdr *)skb->data;
+ if (skb->protocol == htons(ETH_P_IP))
+ tiph = (const struct iphdr *)skb->data;
+ else
+ tiph = &tunnel->parms.iph;
} else {
gre_hlen = tunnel->hlen;
tiph = &tunnel->parms.iph;
@@ -812,6 +816,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
goto tx_error;
}
+ ttl = tiph->ttl;
tos = tiph->tos;
if (tos == 1) {
tos = 0;
@@ -904,11 +909,12 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
dev_kfree_skb(skb);
skb = new_skb;
old_iph = ip_hdr(skb);
+ /* Warning : tiph value might point to freed memory */
}
- skb_reset_transport_header(skb);
skb_push(skb, gre_hlen);
skb_reset_network_header(skb);
+ skb_set_transport_header(skb, sizeof(*iph));
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
IPSKB_REROUTED);
@@ -927,8 +933,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
iph->daddr = fl4.daddr;
iph->saddr = fl4.saddr;
+ iph->ttl = ttl;
- if ((iph->ttl = tiph->ttl) == 0) {
+ if (ttl == 0) {
if (skb->protocol == htons(ETH_P_IP))
iph->ttl = old_iph->ttl;
#if IS_ENABLED(CONFIG_IPV6)
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index d763701cff1b..a2e50ae80b53 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -136,6 +136,8 @@ __be32 ic_myaddr = NONE; /* My IP address */
static __be32 ic_netmask = NONE; /* Netmask for local subnet */
__be32 ic_gateway = NONE; /* Gateway IP address */
+__be32 ic_addrservaddr = NONE; /* IP Address of the IP addresses'server */
+
__be32 ic_servaddr = NONE; /* Boot server IP address */
__be32 root_server_addr = NONE; /* Address of NFS server */
@@ -558,6 +560,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
if (ic_myaddr == NONE)
ic_myaddr = tip;
ic_servaddr = sip;
+ ic_addrservaddr = sip;
ic_got_reply = IC_RARP;
drop_unlock:
@@ -1068,7 +1071,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
ic_servaddr = server_id;
#ifdef IPCONFIG_DEBUG
printk("DHCP: Offered address %pI4 by server %pI4\n",
- &ic_myaddr, &ic_servaddr);
+ &ic_myaddr, &b->iph.saddr);
#endif
/* The DHCP indicated server address takes
* precedence over the bootp header one if
@@ -1113,6 +1116,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
ic_dev = dev;
ic_myaddr = b->your_ip;
ic_servaddr = b->server_ip;
+ ic_addrservaddr = b->iph.saddr;
if (ic_gateway == NONE && b->relay_ip)
ic_gateway = b->relay_ip;
if (ic_nameservers[0] == NONE)
@@ -1268,7 +1272,7 @@ static int __init ic_dynamic(void)
printk("IP-Config: Got %s answer from %pI4, ",
((ic_got_reply & IC_RARP) ? "RARP"
: (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"),
- &ic_servaddr);
+ &ic_addrservaddr);
pr_cont("my address is %pI4\n", &ic_myaddr);
return 0;
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 51f13f8ec724..04b18c1ac345 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -81,6 +81,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
niph->saddr = oiph->daddr;
niph->daddr = oiph->saddr;
+ skb_reset_transport_header(nskb);
tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
memset(tcph, 0, sizeof(*tcph));
tcph->source = oth->dest;
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index da2c8a368f68..eeaff7e4acb5 100644
--- a/net/ipv4/netfilter/iptable_nat.c
+++ b/net/ipv4/netfilter/iptable_nat.c
@@ -124,23 +124,28 @@ nf_nat_ipv4_fn(unsigned int hooknum,
ret = nf_nat_rule_find(skb, hooknum, in, out, ct);
if (ret != NF_ACCEPT)
return ret;
- } else
+ } else {
pr_debug("Already setup manip %s for ct %p\n",
maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
ct);
+ if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
+ goto oif_changed;
+ }
break;
default:
/* ESTABLISHED */
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
ctinfo == IP_CT_ESTABLISHED_REPLY);
- if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) {
- nf_ct_kill_acct(ct, ctinfo, skb);
- return NF_DROP;
- }
+ if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
+ goto oif_changed;
}
return nf_nat_packet(ct, ctinfo, hooknum, skb);
+
+oif_changed:
+ nf_ct_kill_acct(ct, ctinfo, skb);
+ return NF_DROP;
}
static unsigned int
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a13692560e63..a28e4db8a952 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5543,6 +5543,9 @@ slow_path:
if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb))
goto csum_error;
+ if (!th->ack)
+ goto discard;
+
/*
* Standard slow path.
*/
@@ -5551,7 +5554,7 @@ slow_path:
return 0;
step5:
- if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
+ if (tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
goto discard;
/* ts_recent update must be made after we are sure that the packet
@@ -5984,11 +5987,15 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
if (tcp_check_req(sk, skb, req, NULL, true) == NULL)
goto discard;
}
+
+ if (!th->ack)
+ goto discard;
+
if (!tcp_validate_incoming(sk, skb, th, 0))
return 0;
/* step 5: check the ACK field */
- if (th->ack) {
+ if (true) {
int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0;
switch (sk->sk_state) {
@@ -6138,8 +6145,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
}
break;
}
- } else
- goto discard;
+ }
/* ts_recent update must be made after we are sure that the packet
* is in window.