aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-04-22 20:32:51 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-22 20:32:51 -0400
commit6e0895c2ea326cc4bb11e8fa2f654628d5754c31 (patch)
tree7089303ac11a12edc43a8c4fa1b23974e10937ea /net/ipv4
parent55fbbe46e9eb3cbe6c335503f5550855a1128dce (diff)
parent60d509fa6a9c4653a86ad830e4c4b30360b23f0e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/ethernet/emulex/benet/be_main.c drivers/net/ethernet/intel/igb/igb_main.c drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c include/net/scm.h net/batman-adv/routing.c net/ipv4/tcp_input.c The e{uid,gid} --> {uid,gid} credentials fix conflicted with the cleanup in net-next to now pass cred structs around. The be2net driver had a bug fix in 'net' that overlapped with the VLAN interface changes by Patrick McHardy in net-next. An IGB conflict existed because in 'net' the build_skb() support was reverted, and in 'net-next' there was a comment style fix within that code. Several batman-adv conflicts were resolved by making sure that all calls to batadv_is_my_mac() are changed to have a new bat_priv first argument. Eric Dumazet's TS ECR fix in TCP in 'net' conflicted with the F-RTO rewrite in 'net-next', mostly overlapping changes. Thanks to Stephen Rothwell and Antonio Quartulli for help with several of these merge resolutions. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/devinet.c60
-rw-r--r--net/ipv4/esp4.c6
-rw-r--r--net/ipv4/ip_fragment.c14
-rw-r--r--net/ipv4/netfilter/ipt_rpfilter.c8
-rw-r--r--net/ipv4/syncookies.c4
-rw-r--r--net/ipv4/tcp_input.c64
-rw-r--r--net/ipv4/tcp_output.c9
7 files changed, 104 insertions, 61 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 2759dfd576ae..dfc39d4d48b7 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -587,13 +587,16 @@ static void check_lifetime(struct work_struct *work)
587{ 587{
588 unsigned long now, next, next_sec, next_sched; 588 unsigned long now, next, next_sec, next_sched;
589 struct in_ifaddr *ifa; 589 struct in_ifaddr *ifa;
590 struct hlist_node *n;
590 int i; 591 int i;
591 592
592 now = jiffies; 593 now = jiffies;
593 next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY); 594 next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY);
594 595
595 rcu_read_lock();
596 for (i = 0; i < IN4_ADDR_HSIZE; i++) { 596 for (i = 0; i < IN4_ADDR_HSIZE; i++) {
597 bool change_needed = false;
598
599 rcu_read_lock();
597 hlist_for_each_entry_rcu(ifa, &inet_addr_lst[i], hash) { 600 hlist_for_each_entry_rcu(ifa, &inet_addr_lst[i], hash) {
598 unsigned long age; 601 unsigned long age;
599 602
@@ -606,16 +609,7 @@ static void check_lifetime(struct work_struct *work)
606 609
607 if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME && 610 if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
608 age >= ifa->ifa_valid_lft) { 611 age >= ifa->ifa_valid_lft) {
609 struct in_ifaddr **ifap ; 612 change_needed = true;
610
611 rtnl_lock();
612 for (ifap = &ifa->ifa_dev->ifa_list;
613 *ifap != NULL; ifap = &ifa->ifa_next) {
614 if (*ifap == ifa)
615 inet_del_ifa(ifa->ifa_dev,
616 ifap, 1);
617 }
618 rtnl_unlock();
619 } else if (ifa->ifa_preferred_lft == 613 } else if (ifa->ifa_preferred_lft ==
620 INFINITY_LIFE_TIME) { 614 INFINITY_LIFE_TIME) {
621 continue; 615 continue;
@@ -625,10 +619,8 @@ static void check_lifetime(struct work_struct *work)
625 next = ifa->ifa_tstamp + 619 next = ifa->ifa_tstamp +
626 ifa->ifa_valid_lft * HZ; 620 ifa->ifa_valid_lft * HZ;
627 621
628 if (!(ifa->ifa_flags & IFA_F_DEPRECATED)) { 622 if (!(ifa->ifa_flags & IFA_F_DEPRECATED))
629 ifa->ifa_flags |= IFA_F_DEPRECATED; 623 change_needed = true;
630 rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
631 }
632 } else if (time_before(ifa->ifa_tstamp + 624 } else if (time_before(ifa->ifa_tstamp +
633 ifa->ifa_preferred_lft * HZ, 625 ifa->ifa_preferred_lft * HZ,
634 next)) { 626 next)) {
@@ -636,8 +628,42 @@ static void check_lifetime(struct work_struct *work)
636 ifa->ifa_preferred_lft * HZ; 628 ifa->ifa_preferred_lft * HZ;
637 } 629 }
638 } 630 }
631 rcu_read_unlock();
632 if (!change_needed)
633 continue;
634 rtnl_lock();
635 hlist_for_each_entry_safe(ifa, n, &inet_addr_lst[i], hash) {
636 unsigned long age;
637
638 if (ifa->ifa_flags & IFA_F_PERMANENT)
639 continue;
640
641 /* We try to batch several events at once. */
642 age = (now - ifa->ifa_tstamp +
643 ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
644
645 if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME &&
646 age >= ifa->ifa_valid_lft) {
647 struct in_ifaddr **ifap;
648
649 for (ifap = &ifa->ifa_dev->ifa_list;
650 *ifap != NULL; ifap = &(*ifap)->ifa_next) {
651 if (*ifap == ifa) {
652 inet_del_ifa(ifa->ifa_dev,
653 ifap, 1);
654 break;
655 }
656 }
657 } else if (ifa->ifa_preferred_lft !=
658 INFINITY_LIFE_TIME &&
659 age >= ifa->ifa_preferred_lft &&
660 !(ifa->ifa_flags & IFA_F_DEPRECATED)) {
661 ifa->ifa_flags |= IFA_F_DEPRECATED;
662 rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0);
663 }
664 }
665 rtnl_unlock();
639 } 666 }
640 rcu_read_unlock();
641 667
642 next_sec = round_jiffies_up(next); 668 next_sec = round_jiffies_up(next);
643 next_sched = next; 669 next_sched = next;
@@ -804,6 +830,8 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh)
804 return -EEXIST; 830 return -EEXIST;
805 ifa = ifa_existing; 831 ifa = ifa_existing;
806 set_ifa_lifetime(ifa, valid_lft, prefered_lft); 832 set_ifa_lifetime(ifa, valid_lft, prefered_lft);
833 cancel_delayed_work(&check_lifetime_work);
834 schedule_delayed_work(&check_lifetime_work, 0);
807 rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid); 835 rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid);
808 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); 836 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
809 } 837 }
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 3b4f0cd2e63e..4cfe34d4cc96 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -139,8 +139,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
139 139
140 /* skb is pure payload to encrypt */ 140 /* skb is pure payload to encrypt */
141 141
142 err = -ENOMEM;
143
144 esp = x->data; 142 esp = x->data;
145 aead = esp->aead; 143 aead = esp->aead;
146 alen = crypto_aead_authsize(aead); 144 alen = crypto_aead_authsize(aead);
@@ -176,8 +174,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
176 } 174 }
177 175
178 tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); 176 tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen);
179 if (!tmp) 177 if (!tmp) {
178 err = -ENOMEM;
180 goto error; 179 goto error;
180 }
181 181
182 seqhi = esp_tmp_seqhi(tmp); 182 seqhi = esp_tmp_seqhi(tmp);
183 iv = esp_tmp_iv(aead, tmp, seqhilen); 183 iv = esp_tmp_iv(aead, tmp, seqhilen);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 938520668b2f..b66910aaef4d 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -219,8 +219,7 @@ static void ip_expire(unsigned long arg)
219 if (!head->dev) 219 if (!head->dev)
220 goto out_rcu_unlock; 220 goto out_rcu_unlock;
221 221
222 /* skb dst is stale, drop it, and perform route lookup again */ 222 /* skb has no dst, perform route lookup again */
223 skb_dst_drop(head);
224 iph = ip_hdr(head); 223 iph = ip_hdr(head);
225 err = ip_route_input_noref(head, iph->daddr, iph->saddr, 224 err = ip_route_input_noref(head, iph->daddr, iph->saddr,
226 iph->tos, head->dev); 225 iph->tos, head->dev);
@@ -494,9 +493,16 @@ found:
494 qp->q.max_size = skb->len + ihl; 493 qp->q.max_size = skb->len + ihl;
495 494
496 if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && 495 if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
497 qp->q.meat == qp->q.len) 496 qp->q.meat == qp->q.len) {
498 return ip_frag_reasm(qp, prev, dev); 497 unsigned long orefdst = skb->_skb_refdst;
499 498
499 skb->_skb_refdst = 0UL;
500 err = ip_frag_reasm(qp, prev, dev);
501 skb->_skb_refdst = orefdst;
502 return err;
503 }
504
505 skb_dst_drop(skb);
500 inet_frag_lru_move(&qp->q); 506 inet_frag_lru_move(&qp->q);
501 return -EINPROGRESS; 507 return -EINPROGRESS;
502 508
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c
index c30130062cd6..c49dcd0284a0 100644
--- a/net/ipv4/netfilter/ipt_rpfilter.c
+++ b/net/ipv4/netfilter/ipt_rpfilter.c
@@ -66,6 +66,12 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4,
66 return dev_match; 66 return dev_match;
67} 67}
68 68
69static bool rpfilter_is_local(const struct sk_buff *skb)
70{
71 const struct rtable *rt = skb_rtable(skb);
72 return rt && (rt->rt_flags & RTCF_LOCAL);
73}
74
69static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) 75static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
70{ 76{
71 const struct xt_rpfilter_info *info; 77 const struct xt_rpfilter_info *info;
@@ -76,7 +82,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
76 info = par->matchinfo; 82 info = par->matchinfo;
77 invert = info->flags & XT_RPFILTER_INVERT; 83 invert = info->flags & XT_RPFILTER_INVERT;
78 84
79 if (par->in->flags & IFF_LOOPBACK) 85 if (rpfilter_is_local(skb))
80 return true ^ invert; 86 return true ^ invert;
81 87
82 iph = ip_hdr(skb); 88 iph = ip_hdr(skb);
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 7f4a5cb8f8d0..b05c96e7af8b 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -348,8 +348,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
348 * hasn't changed since we received the original syn, but I see 348 * hasn't changed since we received the original syn, but I see
349 * no easy way to do this. 349 * no easy way to do this.
350 */ 350 */
351 flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), 351 flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark,
352 RT_SCOPE_UNIVERSE, IPPROTO_TCP, 352 RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP,
353 inet_sk_flowi_flags(sk), 353 inet_sk_flowi_flags(sk),
354 (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, 354 (opt && opt->srr) ? opt->faddr : ireq->rmt_addr,
355 ireq->loc_addr, th->source, th->dest); 355 ireq->loc_addr, th->source, th->dest);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 6d9ca35f0c35..aafd052865ba 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -111,6 +111,7 @@ int sysctl_tcp_early_retrans __read_mostly = 3;
111#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ 111#define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */
112#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ 112#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */
113#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ 113#define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */
114#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */
114 115
115#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) 116#define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED)
116#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) 117#define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
@@ -3265,6 +3266,27 @@ static void tcp_send_challenge_ack(struct sock *sk)
3265 } 3266 }
3266} 3267}
3267 3268
3269static void tcp_store_ts_recent(struct tcp_sock *tp)
3270{
3271 tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
3272 tp->rx_opt.ts_recent_stamp = get_seconds();
3273}
3274
3275static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
3276{
3277 if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) {
3278 /* PAWS bug workaround wrt. ACK frames, the PAWS discard
3279 * extra check below makes sure this can only happen
3280 * for pure ACK frames. -DaveM
3281 *
3282 * Not only, also it occurs for expired timestamps.
3283 */
3284
3285 if (tcp_paws_check(&tp->rx_opt, 0))
3286 tcp_store_ts_recent(tp);
3287 }
3288}
3289
3268/* This routine deals with acks during a TLP episode. 3290/* This routine deals with acks during a TLP episode.
3269 * Ref: loss detection algorithm in draft-dukkipati-tcpm-tcp-loss-probe. 3291 * Ref: loss detection algorithm in draft-dukkipati-tcpm-tcp-loss-probe.
3270 */ 3292 */
@@ -3340,6 +3362,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3340 prior_fackets = tp->fackets_out; 3362 prior_fackets = tp->fackets_out;
3341 prior_in_flight = tcp_packets_in_flight(tp); 3363 prior_in_flight = tcp_packets_in_flight(tp);
3342 3364
3365 /* ts_recent update must be made after we are sure that the packet
3366 * is in window.
3367 */
3368 if (flag & FLAG_UPDATE_TS_RECENT)
3369 tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
3370
3343 if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) { 3371 if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
3344 /* Window is constant, pure forward advance. 3372 /* Window is constant, pure forward advance.
3345 * No more checks are required. 3373 * No more checks are required.
@@ -3636,27 +3664,6 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th)
3636EXPORT_SYMBOL(tcp_parse_md5sig_option); 3664EXPORT_SYMBOL(tcp_parse_md5sig_option);
3637#endif 3665#endif
3638 3666
3639static inline void tcp_store_ts_recent(struct tcp_sock *tp)
3640{
3641 tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
3642 tp->rx_opt.ts_recent_stamp = get_seconds();
3643}
3644
3645static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
3646{
3647 if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) {
3648 /* PAWS bug workaround wrt. ACK frames, the PAWS discard
3649 * extra check below makes sure this can only happen
3650 * for pure ACK frames. -DaveM
3651 *
3652 * Not only, also it occurs for expired timestamps.
3653 */
3654
3655 if (tcp_paws_check(&tp->rx_opt, 0))
3656 tcp_store_ts_recent(tp);
3657 }
3658}
3659
3660/* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM 3667/* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM
3661 * 3668 *
3662 * It is not fatal. If this ACK does _not_ change critical state (seqs, window) 3669 * It is not fatal. If this ACK does _not_ change critical state (seqs, window)
@@ -5250,14 +5257,9 @@ slow_path:
5250 return 0; 5257 return 0;
5251 5258
5252step5: 5259step5:
5253 if (tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) 5260 if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0)
5254 goto discard; 5261 goto discard;
5255 5262
5256 /* ts_recent update must be made after we are sure that the packet
5257 * is in window.
5258 */
5259 tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
5260
5261 tcp_rcv_rtt_measure_ts(sk, skb); 5263 tcp_rcv_rtt_measure_ts(sk, skb);
5262 5264
5263 /* Process urgent data. */ 5265 /* Process urgent data. */
@@ -5666,7 +5668,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5666 5668
5667 /* step 5: check the ACK field */ 5669 /* step 5: check the ACK field */
5668 if (true) { 5670 if (true) {
5669 int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0; 5671 int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH |
5672 FLAG_UPDATE_TS_RECENT) > 0;
5670 5673
5671 switch (sk->sk_state) { 5674 switch (sk->sk_state) {
5672 case TCP_SYN_RECV: 5675 case TCP_SYN_RECV:
@@ -5817,11 +5820,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5817 } 5820 }
5818 } 5821 }
5819 5822
5820 /* ts_recent update must be made after we are sure that the packet
5821 * is in window.
5822 */
5823 tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
5824
5825 /* step 6: check the URG bit */ 5823 /* step 6: check the URG bit */
5826 tcp_urg(sk, skb, th); 5824 tcp_urg(sk, skb, th);
5827 5825
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 5f28131eb37e..b735c23a961d 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2353,8 +2353,12 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
2353 */ 2353 */
2354 TCP_SKB_CB(skb)->when = tcp_time_stamp; 2354 TCP_SKB_CB(skb)->when = tcp_time_stamp;
2355 2355
2356 /* make sure skb->data is aligned on arches that require it */ 2356 /* make sure skb->data is aligned on arches that require it
2357 if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { 2357 * and check if ack-trimming & collapsing extended the headroom
2358 * beyond what csum_start can cover.
2359 */
2360 if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) ||
2361 skb_headroom(skb) >= 0xFFFF)) {
2358 struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, 2362 struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
2359 GFP_ATOMIC); 2363 GFP_ATOMIC);
2360 return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : 2364 return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
@@ -2666,6 +2670,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2666 skb_reserve(skb, MAX_TCP_HEADER); 2670 skb_reserve(skb, MAX_TCP_HEADER);
2667 2671
2668 skb_dst_set(skb, dst); 2672 skb_dst_set(skb, dst);
2673 security_skb_owned_by(skb, sk);
2669 2674
2670 mss = dst_metric_advmss(dst); 2675 mss = dst_metric_advmss(dst);
2671 if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) 2676 if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)