diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/devinet.c | 15 | ||||
-rw-r--r-- | net/ipv4/inet_timewait_sock.c | 35 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 1 |
3 files changed, 48 insertions, 3 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 91d3d96805d0..b12dae2b0b2d 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1029,6 +1029,11 @@ skip: | |||
1029 | } | 1029 | } |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | static inline bool inetdev_valid_mtu(unsigned mtu) | ||
1033 | { | ||
1034 | return mtu >= 68; | ||
1035 | } | ||
1036 | |||
1032 | /* Called only under RTNL semaphore */ | 1037 | /* Called only under RTNL semaphore */ |
1033 | 1038 | ||
1034 | static int inetdev_event(struct notifier_block *this, unsigned long event, | 1039 | static int inetdev_event(struct notifier_block *this, unsigned long event, |
@@ -1048,6 +1053,10 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
1048 | IN_DEV_CONF_SET(in_dev, NOXFRM, 1); | 1053 | IN_DEV_CONF_SET(in_dev, NOXFRM, 1); |
1049 | IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); | 1054 | IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); |
1050 | } | 1055 | } |
1056 | } else if (event == NETDEV_CHANGEMTU) { | ||
1057 | /* Re-enabling IP */ | ||
1058 | if (inetdev_valid_mtu(dev->mtu)) | ||
1059 | in_dev = inetdev_init(dev); | ||
1051 | } | 1060 | } |
1052 | goto out; | 1061 | goto out; |
1053 | } | 1062 | } |
@@ -1058,7 +1067,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
1058 | dev->ip_ptr = NULL; | 1067 | dev->ip_ptr = NULL; |
1059 | break; | 1068 | break; |
1060 | case NETDEV_UP: | 1069 | case NETDEV_UP: |
1061 | if (dev->mtu < 68) | 1070 | if (!inetdev_valid_mtu(dev->mtu)) |
1062 | break; | 1071 | break; |
1063 | if (dev->flags & IFF_LOOPBACK) { | 1072 | if (dev->flags & IFF_LOOPBACK) { |
1064 | struct in_ifaddr *ifa; | 1073 | struct in_ifaddr *ifa; |
@@ -1080,9 +1089,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
1080 | ip_mc_down(in_dev); | 1089 | ip_mc_down(in_dev); |
1081 | break; | 1090 | break; |
1082 | case NETDEV_CHANGEMTU: | 1091 | case NETDEV_CHANGEMTU: |
1083 | if (dev->mtu >= 68) | 1092 | if (inetdev_valid_mtu(dev->mtu)) |
1084 | break; | 1093 | break; |
1085 | /* MTU falled under 68, disable IP */ | 1094 | /* disable IP when MTU is not enough */ |
1086 | case NETDEV_UNREGISTER: | 1095 | case NETDEV_UNREGISTER: |
1087 | inetdev_destroy(in_dev); | 1096 | inetdev_destroy(in_dev); |
1088 | break; | 1097 | break; |
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index d985bd613d25..743f011b9a84 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c | |||
@@ -409,3 +409,38 @@ out: | |||
409 | } | 409 | } |
410 | 410 | ||
411 | EXPORT_SYMBOL_GPL(inet_twdr_twcal_tick); | 411 | EXPORT_SYMBOL_GPL(inet_twdr_twcal_tick); |
412 | |||
413 | void inet_twsk_purge(struct net *net, struct inet_hashinfo *hashinfo, | ||
414 | struct inet_timewait_death_row *twdr, int family) | ||
415 | { | ||
416 | struct inet_timewait_sock *tw; | ||
417 | struct sock *sk; | ||
418 | struct hlist_node *node; | ||
419 | int h; | ||
420 | |||
421 | local_bh_disable(); | ||
422 | for (h = 0; h < (hashinfo->ehash_size); h++) { | ||
423 | struct inet_ehash_bucket *head = | ||
424 | inet_ehash_bucket(hashinfo, h); | ||
425 | rwlock_t *lock = inet_ehash_lockp(hashinfo, h); | ||
426 | restart: | ||
427 | write_lock(lock); | ||
428 | sk_for_each(sk, node, &head->twchain) { | ||
429 | |||
430 | tw = inet_twsk(sk); | ||
431 | if (!net_eq(twsk_net(tw), net) || | ||
432 | tw->tw_family != family) | ||
433 | continue; | ||
434 | |||
435 | atomic_inc(&tw->tw_refcnt); | ||
436 | write_unlock(lock); | ||
437 | inet_twsk_deschedule(tw, twdr); | ||
438 | inet_twsk_put(tw); | ||
439 | |||
440 | goto restart; | ||
441 | } | ||
442 | write_unlock(lock); | ||
443 | } | ||
444 | local_bh_enable(); | ||
445 | } | ||
446 | EXPORT_SYMBOL_GPL(inet_twsk_purge); | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 37ca3843c40b..3dfbc21e555a 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -2388,6 +2388,7 @@ static int __net_init tcp_sk_init(struct net *net) | |||
2388 | static void __net_exit tcp_sk_exit(struct net *net) | 2388 | static void __net_exit tcp_sk_exit(struct net *net) |
2389 | { | 2389 | { |
2390 | inet_ctl_sock_destroy(net->ipv4.tcp_sock); | 2390 | inet_ctl_sock_destroy(net->ipv4.tcp_sock); |
2391 | inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET); | ||
2391 | } | 2392 | } |
2392 | 2393 | ||
2393 | static struct pernet_operations __net_initdata tcp_sk_ops = { | 2394 | static struct pernet_operations __net_initdata tcp_sk_ops = { |