diff options
Diffstat (limited to 'net')
46 files changed, 290 insertions, 159 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 9096bcb08132..ee070722a3a3 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -463,7 +463,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
| 463 | 463 | ||
| 464 | case NETDEV_PRE_TYPE_CHANGE: | 464 | case NETDEV_PRE_TYPE_CHANGE: |
| 465 | /* Forbid underlaying device to change its type. */ | 465 | /* Forbid underlaying device to change its type. */ |
| 466 | return NOTIFY_BAD; | 466 | if (vlan_uses_dev(dev)) |
| 467 | return NOTIFY_BAD; | ||
| 468 | break; | ||
| 467 | 469 | ||
| 468 | case NETDEV_NOTIFY_PEERS: | 470 | case NETDEV_NOTIFY_PEERS: |
| 469 | case NETDEV_BONDING_FAILOVER: | 471 | case NETDEV_BONDING_FAILOVER: |
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index fbbf1fa00940..65e06abe023f 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
| @@ -366,6 +366,13 @@ EXPORT_SYMBOL(vlan_vids_del_by_dev); | |||
| 366 | 366 | ||
| 367 | bool vlan_uses_dev(const struct net_device *dev) | 367 | bool vlan_uses_dev(const struct net_device *dev) |
| 368 | { | 368 | { |
| 369 | return rtnl_dereference(dev->vlan_info) ? true : false; | 369 | struct vlan_info *vlan_info; |
| 370 | |||
| 371 | ASSERT_RTNL(); | ||
| 372 | |||
| 373 | vlan_info = rtnl_dereference(dev->vlan_info); | ||
| 374 | if (!vlan_info) | ||
| 375 | return false; | ||
| 376 | return vlan_info->grp.nr_vlan_devs ? true : false; | ||
| 370 | } | 377 | } |
| 371 | EXPORT_SYMBOL(vlan_uses_dev); | 378 | EXPORT_SYMBOL(vlan_uses_dev); |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 0a9084ad19a6..fd8d5afec0dd 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
| @@ -1167,6 +1167,8 @@ int batadv_bla_init(struct batadv_priv *bat_priv) | |||
| 1167 | uint16_t crc; | 1167 | uint16_t crc; |
| 1168 | unsigned long entrytime; | 1168 | unsigned long entrytime; |
| 1169 | 1169 | ||
| 1170 | spin_lock_init(&bat_priv->bla.bcast_duplist_lock); | ||
| 1171 | |||
| 1170 | batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n"); | 1172 | batadv_dbg(BATADV_DBG_BLA, bat_priv, "bla hash registering\n"); |
| 1171 | 1173 | ||
| 1172 | /* setting claim destination address */ | 1174 | /* setting claim destination address */ |
| @@ -1210,8 +1212,8 @@ int batadv_bla_init(struct batadv_priv *bat_priv) | |||
| 1210 | /** | 1212 | /** |
| 1211 | * batadv_bla_check_bcast_duplist | 1213 | * batadv_bla_check_bcast_duplist |
| 1212 | * @bat_priv: the bat priv with all the soft interface information | 1214 | * @bat_priv: the bat priv with all the soft interface information |
| 1213 | * @bcast_packet: originator mac address | 1215 | * @bcast_packet: encapsulated broadcast frame plus batman header |
| 1214 | * @hdr_size: maximum length of the frame | 1216 | * @bcast_packet_len: length of encapsulated broadcast frame plus batman header |
| 1215 | * | 1217 | * |
| 1216 | * check if it is on our broadcast list. Another gateway might | 1218 | * check if it is on our broadcast list. Another gateway might |
| 1217 | * have sent the same packet because it is connected to the same backbone, | 1219 | * have sent the same packet because it is connected to the same backbone, |
| @@ -1224,20 +1226,22 @@ int batadv_bla_init(struct batadv_priv *bat_priv) | |||
| 1224 | */ | 1226 | */ |
| 1225 | int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | 1227 | int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, |
| 1226 | struct batadv_bcast_packet *bcast_packet, | 1228 | struct batadv_bcast_packet *bcast_packet, |
| 1227 | int hdr_size) | 1229 | int bcast_packet_len) |
| 1228 | { | 1230 | { |
| 1229 | int i, length, curr; | 1231 | int i, length, curr, ret = 0; |
| 1230 | uint8_t *content; | 1232 | uint8_t *content; |
| 1231 | uint16_t crc; | 1233 | uint16_t crc; |
| 1232 | struct batadv_bcast_duplist_entry *entry; | 1234 | struct batadv_bcast_duplist_entry *entry; |
| 1233 | 1235 | ||
| 1234 | length = hdr_size - sizeof(*bcast_packet); | 1236 | length = bcast_packet_len - sizeof(*bcast_packet); |
| 1235 | content = (uint8_t *)bcast_packet; | 1237 | content = (uint8_t *)bcast_packet; |
| 1236 | content += sizeof(*bcast_packet); | 1238 | content += sizeof(*bcast_packet); |
| 1237 | 1239 | ||
| 1238 | /* calculate the crc ... */ | 1240 | /* calculate the crc ... */ |
| 1239 | crc = crc16(0, content, length); | 1241 | crc = crc16(0, content, length); |
| 1240 | 1242 | ||
| 1243 | spin_lock_bh(&bat_priv->bla.bcast_duplist_lock); | ||
| 1244 | |||
| 1241 | for (i = 0; i < BATADV_DUPLIST_SIZE; i++) { | 1245 | for (i = 0; i < BATADV_DUPLIST_SIZE; i++) { |
| 1242 | curr = (bat_priv->bla.bcast_duplist_curr + i); | 1246 | curr = (bat_priv->bla.bcast_duplist_curr + i); |
| 1243 | curr %= BATADV_DUPLIST_SIZE; | 1247 | curr %= BATADV_DUPLIST_SIZE; |
| @@ -1259,9 +1263,12 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | |||
| 1259 | /* this entry seems to match: same crc, not too old, | 1263 | /* this entry seems to match: same crc, not too old, |
| 1260 | * and from another gw. therefore return 1 to forbid it. | 1264 | * and from another gw. therefore return 1 to forbid it. |
| 1261 | */ | 1265 | */ |
| 1262 | return 1; | 1266 | ret = 1; |
| 1267 | goto out; | ||
| 1263 | } | 1268 | } |
| 1264 | /* not found, add a new entry (overwrite the oldest entry) */ | 1269 | /* not found, add a new entry (overwrite the oldest entry) |
| 1270 | * and allow it, its the first occurence. | ||
| 1271 | */ | ||
| 1265 | curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); | 1272 | curr = (bat_priv->bla.bcast_duplist_curr + BATADV_DUPLIST_SIZE - 1); |
| 1266 | curr %= BATADV_DUPLIST_SIZE; | 1273 | curr %= BATADV_DUPLIST_SIZE; |
| 1267 | entry = &bat_priv->bla.bcast_duplist[curr]; | 1274 | entry = &bat_priv->bla.bcast_duplist[curr]; |
| @@ -1270,8 +1277,10 @@ int batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv, | |||
| 1270 | memcpy(entry->orig, bcast_packet->orig, ETH_ALEN); | 1277 | memcpy(entry->orig, bcast_packet->orig, ETH_ALEN); |
| 1271 | bat_priv->bla.bcast_duplist_curr = curr; | 1278 | bat_priv->bla.bcast_duplist_curr = curr; |
| 1272 | 1279 | ||
| 1273 | /* allow it, its the first occurence. */ | 1280 | out: |
| 1274 | return 0; | 1281 | spin_unlock_bh(&bat_priv->bla.bcast_duplist_lock); |
| 1282 | |||
| 1283 | return ret; | ||
| 1275 | } | 1284 | } |
| 1276 | 1285 | ||
| 1277 | 1286 | ||
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 939fc01371df..376b4cc6ca82 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
| @@ -1124,8 +1124,14 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, | |||
| 1124 | 1124 | ||
| 1125 | spin_unlock_bh(&orig_node->bcast_seqno_lock); | 1125 | spin_unlock_bh(&orig_node->bcast_seqno_lock); |
| 1126 | 1126 | ||
| 1127 | /* keep skb linear for crc calculation */ | ||
| 1128 | if (skb_linearize(skb) < 0) | ||
| 1129 | goto out; | ||
| 1130 | |||
| 1131 | bcast_packet = (struct batadv_bcast_packet *)skb->data; | ||
| 1132 | |||
| 1127 | /* check whether this has been sent by another originator before */ | 1133 | /* check whether this has been sent by another originator before */ |
| 1128 | if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, hdr_size)) | 1134 | if (batadv_bla_check_bcast_duplist(bat_priv, bcast_packet, skb->len)) |
| 1129 | goto out; | 1135 | goto out; |
| 1130 | 1136 | ||
| 1131 | /* rebroadcast packet */ | 1137 | /* rebroadcast packet */ |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 2ed82caacdca..ac1e07a80454 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
| @@ -205,6 +205,8 @@ struct batadv_priv_bla { | |||
| 205 | struct batadv_hashtable *backbone_hash; | 205 | struct batadv_hashtable *backbone_hash; |
| 206 | struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; | 206 | struct batadv_bcast_duplist_entry bcast_duplist[BATADV_DUPLIST_SIZE]; |
| 207 | int bcast_duplist_curr; | 207 | int bcast_duplist_curr; |
| 208 | /* protects bcast_duplist and bcast_duplist_curr */ | ||
| 209 | spinlock_t bcast_duplist_lock; | ||
| 208 | struct batadv_bla_claim_dst claim_dest; | 210 | struct batadv_bla_claim_dst claim_dest; |
| 209 | struct delayed_work work; | 211 | struct delayed_work work; |
| 210 | }; | 212 | }; |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 159aa8bef9e7..3ef1759403b4 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
| @@ -2300,10 +2300,11 @@ restart: | |||
| 2300 | mutex_unlock(&con->mutex); | 2300 | mutex_unlock(&con->mutex); |
| 2301 | return; | 2301 | return; |
| 2302 | } else { | 2302 | } else { |
| 2303 | con->ops->put(con); | ||
| 2304 | dout("con_work %p FAILED to back off %lu\n", con, | 2303 | dout("con_work %p FAILED to back off %lu\n", con, |
| 2305 | con->delay); | 2304 | con->delay); |
| 2305 | set_bit(CON_FLAG_BACKOFF, &con->flags); | ||
| 2306 | } | 2306 | } |
| 2307 | goto done; | ||
| 2307 | } | 2308 | } |
| 2308 | 2309 | ||
| 2309 | if (con->state == CON_STATE_STANDBY) { | 2310 | if (con->state == CON_STATE_STANDBY) { |
| @@ -2749,7 +2750,8 @@ static int ceph_con_in_msg_alloc(struct ceph_connection *con, int *skip) | |||
| 2749 | msg = con->ops->alloc_msg(con, hdr, skip); | 2750 | msg = con->ops->alloc_msg(con, hdr, skip); |
| 2750 | mutex_lock(&con->mutex); | 2751 | mutex_lock(&con->mutex); |
| 2751 | if (con->state != CON_STATE_OPEN) { | 2752 | if (con->state != CON_STATE_OPEN) { |
| 2752 | ceph_msg_put(msg); | 2753 | if (msg) |
| 2754 | ceph_msg_put(msg); | ||
| 2753 | return -EAGAIN; | 2755 | return -EAGAIN; |
| 2754 | } | 2756 | } |
| 2755 | con->in_msg = msg; | 2757 | con->in_msg = msg; |
diff --git a/net/core/dev.c b/net/core/dev.c index 09cb3f6dc40c..bda6d004f9f0 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1666,7 +1666,7 @@ static inline int deliver_skb(struct sk_buff *skb, | |||
| 1666 | 1666 | ||
| 1667 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) | 1667 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) |
| 1668 | { | 1668 | { |
| 1669 | if (ptype->af_packet_priv == NULL) | 1669 | if (!ptype->af_packet_priv || !skb->sk) |
| 1670 | return false; | 1670 | return false; |
| 1671 | 1671 | ||
| 1672 | if (ptype->id_match) | 1672 | if (ptype->id_match) |
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 87cc17db2d56..b079c7bbc157 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c | |||
| @@ -319,7 +319,8 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, | |||
| 319 | */ | 319 | */ |
| 320 | ha = list_first_entry(&dev->dev_addrs.list, | 320 | ha = list_first_entry(&dev->dev_addrs.list, |
| 321 | struct netdev_hw_addr, list); | 321 | struct netdev_hw_addr, list); |
| 322 | if (ha->addr == dev->dev_addr && ha->refcount == 1) | 322 | if (!memcmp(ha->addr, addr, dev->addr_len) && |
| 323 | ha->type == addr_type && ha->refcount == 1) | ||
| 323 | return -ENOENT; | 324 | return -ENOENT; |
| 324 | 325 | ||
| 325 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, | 326 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 76d4c2c3c89b..fad649ae4dec 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -2192,7 +2192,8 @@ static int nlmsg_populate_fdb(struct sk_buff *skb, | |||
| 2192 | goto skip; | 2192 | goto skip; |
| 2193 | 2193 | ||
| 2194 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, | 2194 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, |
| 2195 | portid, seq, 0, NTF_SELF); | 2195 | portid, seq, |
| 2196 | RTM_NEWNEIGH, NTF_SELF); | ||
| 2196 | if (err < 0) | 2197 | if (err < 0) |
| 2197 | return err; | 2198 | return err; |
| 2198 | skip: | 2199 | skip: |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 6e04b1fa11f2..4007c1437fda 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -3379,10 +3379,12 @@ EXPORT_SYMBOL(__skb_warn_lro_forwarding); | |||
| 3379 | 3379 | ||
| 3380 | void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) | 3380 | void kfree_skb_partial(struct sk_buff *skb, bool head_stolen) |
| 3381 | { | 3381 | { |
| 3382 | if (head_stolen) | 3382 | if (head_stolen) { |
| 3383 | skb_release_head_state(skb); | ||
| 3383 | kmem_cache_free(skbuff_head_cache, skb); | 3384 | kmem_cache_free(skbuff_head_cache, skb); |
| 3384 | else | 3385 | } else { |
| 3385 | __kfree_skb(skb); | 3386 | __kfree_skb(skb); |
| 3387 | } | ||
| 3386 | } | 3388 | } |
| 3387 | EXPORT_SYMBOL(kfree_skb_partial); | 3389 | EXPORT_SYMBOL(kfree_skb_partial); |
| 3388 | 3390 | ||
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 535584c00f91..0c34bfabc11f 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -892,13 +892,16 @@ static int __inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, | |||
| 892 | struct inet_diag_req_v2 *r, struct nlattr *bc) | 892 | struct inet_diag_req_v2 *r, struct nlattr *bc) |
| 893 | { | 893 | { |
| 894 | const struct inet_diag_handler *handler; | 894 | const struct inet_diag_handler *handler; |
| 895 | int err = 0; | ||
| 895 | 896 | ||
| 896 | handler = inet_diag_lock_handler(r->sdiag_protocol); | 897 | handler = inet_diag_lock_handler(r->sdiag_protocol); |
| 897 | if (!IS_ERR(handler)) | 898 | if (!IS_ERR(handler)) |
| 898 | handler->dump(skb, cb, r, bc); | 899 | handler->dump(skb, cb, r, bc); |
| 900 | else | ||
| 901 | err = PTR_ERR(handler); | ||
| 899 | inet_diag_unlock_handler(handler); | 902 | inet_diag_unlock_handler(handler); |
| 900 | 903 | ||
| 901 | return skb->len; | 904 | return err ? : skb->len; |
| 902 | } | 905 | } |
| 903 | 906 | ||
| 904 | static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) | 907 | static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 5eea4a811042..14bbfcf717ac 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
| 457 | struct inet_sock *inet = inet_sk(sk); | 457 | struct inet_sock *inet = inet_sk(sk); |
| 458 | int val = 0, err; | 458 | int val = 0, err; |
| 459 | 459 | ||
| 460 | if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) | | 460 | switch (optname) { |
| 461 | (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) | | 461 | case IP_PKTINFO: |
| 462 | (1<<IP_RETOPTS) | (1<<IP_TOS) | | 462 | case IP_RECVTTL: |
| 463 | (1<<IP_TTL) | (1<<IP_HDRINCL) | | 463 | case IP_RECVOPTS: |
| 464 | (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | | 464 | case IP_RECVTOS: |
| 465 | (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | | 465 | case IP_RETOPTS: |
| 466 | (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) | | 466 | case IP_TOS: |
| 467 | (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) || | 467 | case IP_TTL: |
| 468 | optname == IP_UNICAST_IF || | 468 | case IP_HDRINCL: |
| 469 | optname == IP_MULTICAST_TTL || | 469 | case IP_MTU_DISCOVER: |
| 470 | optname == IP_MULTICAST_ALL || | 470 | case IP_RECVERR: |
| 471 | optname == IP_MULTICAST_LOOP || | 471 | case IP_ROUTER_ALERT: |
| 472 | optname == IP_RECVORIGDSTADDR) { | 472 | case IP_FREEBIND: |
| 473 | case IP_PASSSEC: | ||
| 474 | case IP_TRANSPARENT: | ||
| 475 | case IP_MINTTL: | ||
| 476 | case IP_NODEFRAG: | ||
| 477 | case IP_UNICAST_IF: | ||
| 478 | case IP_MULTICAST_TTL: | ||
| 479 | case IP_MULTICAST_ALL: | ||
| 480 | case IP_MULTICAST_LOOP: | ||
| 481 | case IP_RECVORIGDSTADDR: | ||
| 473 | if (optlen >= sizeof(int)) { | 482 | if (optlen >= sizeof(int)) { |
| 474 | if (get_user(val, (int __user *) optval)) | 483 | if (get_user(val, (int __user *) optval)) |
| 475 | return -EFAULT; | 484 | return -EFAULT; |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 1831092f999f..858fddf6482a 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
| @@ -338,12 +338,17 @@ static int vti_rcv(struct sk_buff *skb) | |||
| 338 | if (tunnel != NULL) { | 338 | if (tunnel != NULL) { |
| 339 | struct pcpu_tstats *tstats; | 339 | struct pcpu_tstats *tstats; |
| 340 | 340 | ||
| 341 | if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) | ||
| 342 | return -1; | ||
| 343 | |||
| 341 | tstats = this_cpu_ptr(tunnel->dev->tstats); | 344 | tstats = this_cpu_ptr(tunnel->dev->tstats); |
| 342 | u64_stats_update_begin(&tstats->syncp); | 345 | u64_stats_update_begin(&tstats->syncp); |
| 343 | tstats->rx_packets++; | 346 | tstats->rx_packets++; |
| 344 | tstats->rx_bytes += skb->len; | 347 | tstats->rx_bytes += skb->len; |
| 345 | u64_stats_update_end(&tstats->syncp); | 348 | u64_stats_update_end(&tstats->syncp); |
| 346 | 349 | ||
| 350 | skb->mark = 0; | ||
| 351 | secpath_reset(skb); | ||
| 347 | skb->dev = tunnel->dev; | 352 | skb->dev = tunnel->dev; |
| 348 | return 1; | 353 | return 1; |
| 349 | } | 354 | } |
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c index 9e0ffaf1d942..a82047282dbb 100644 --- a/net/ipv4/netfilter/iptable_nat.c +++ b/net/ipv4/netfilter/iptable_nat.c | |||
| @@ -184,7 +184,8 @@ nf_nat_ipv4_out(unsigned int hooknum, | |||
| 184 | 184 | ||
| 185 | if ((ct->tuplehash[dir].tuple.src.u3.ip != | 185 | if ((ct->tuplehash[dir].tuple.src.u3.ip != |
| 186 | ct->tuplehash[!dir].tuple.dst.u3.ip) || | 186 | ct->tuplehash[!dir].tuple.dst.u3.ip) || |
| 187 | (ct->tuplehash[dir].tuple.src.u.all != | 187 | (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && |
| 188 | ct->tuplehash[dir].tuple.src.u.all != | ||
| 188 | ct->tuplehash[!dir].tuple.dst.u.all)) | 189 | ct->tuplehash[!dir].tuple.dst.u.all)) |
| 189 | if (nf_xfrm_me_harder(skb, AF_INET) < 0) | 190 | if (nf_xfrm_me_harder(skb, AF_INET) < 0) |
| 190 | ret = NF_DROP; | 191 | ret = NF_DROP; |
| @@ -221,6 +222,7 @@ nf_nat_ipv4_local_fn(unsigned int hooknum, | |||
| 221 | } | 222 | } |
| 222 | #ifdef CONFIG_XFRM | 223 | #ifdef CONFIG_XFRM |
| 223 | else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && | 224 | else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) && |
| 225 | ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP && | ||
| 224 | ct->tuplehash[dir].tuple.dst.u.all != | 226 | ct->tuplehash[dir].tuple.dst.u.all != |
| 225 | ct->tuplehash[!dir].tuple.src.u.all) | 227 | ct->tuplehash[!dir].tuple.src.u.all) |
| 226 | if (nf_xfrm_me_harder(skb, AF_INET) < 0) | 228 | if (nf_xfrm_me_harder(skb, AF_INET) < 0) |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 432f4bb77238..a8c651216fa6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1163,8 +1163,12 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, | |||
| 1163 | spin_lock_bh(&fnhe_lock); | 1163 | spin_lock_bh(&fnhe_lock); |
| 1164 | 1164 | ||
| 1165 | if (daddr == fnhe->fnhe_daddr) { | 1165 | if (daddr == fnhe->fnhe_daddr) { |
| 1166 | struct rtable *orig; | 1166 | struct rtable *orig = rcu_dereference(fnhe->fnhe_rth); |
| 1167 | 1167 | if (orig && rt_is_expired(orig)) { | |
| 1168 | fnhe->fnhe_gw = 0; | ||
| 1169 | fnhe->fnhe_pmtu = 0; | ||
| 1170 | fnhe->fnhe_expires = 0; | ||
| 1171 | } | ||
| 1168 | if (fnhe->fnhe_pmtu) { | 1172 | if (fnhe->fnhe_pmtu) { |
| 1169 | unsigned long expires = fnhe->fnhe_expires; | 1173 | unsigned long expires = fnhe->fnhe_expires; |
| 1170 | unsigned long diff = expires - jiffies; | 1174 | unsigned long diff = expires - jiffies; |
| @@ -1181,7 +1185,6 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, | |||
| 1181 | } else if (!rt->rt_gateway) | 1185 | } else if (!rt->rt_gateway) |
| 1182 | rt->rt_gateway = daddr; | 1186 | rt->rt_gateway = daddr; |
| 1183 | 1187 | ||
| 1184 | orig = rcu_dereference(fnhe->fnhe_rth); | ||
| 1185 | rcu_assign_pointer(fnhe->fnhe_rth, rt); | 1188 | rcu_assign_pointer(fnhe->fnhe_rth, rt); |
| 1186 | if (orig) | 1189 | if (orig) |
| 1187 | rt_free(orig); | 1190 | rt_free(orig); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f32c02e2a543..083092e3aed6 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -549,14 +549,12 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
| 549 | !tp->urg_data || | 549 | !tp->urg_data || |
| 550 | before(tp->urg_seq, tp->copied_seq) || | 550 | before(tp->urg_seq, tp->copied_seq) || |
| 551 | !before(tp->urg_seq, tp->rcv_nxt)) { | 551 | !before(tp->urg_seq, tp->rcv_nxt)) { |
| 552 | struct sk_buff *skb; | ||
| 553 | 552 | ||
| 554 | answ = tp->rcv_nxt - tp->copied_seq; | 553 | answ = tp->rcv_nxt - tp->copied_seq; |
| 555 | 554 | ||
| 556 | /* Subtract 1, if FIN is in queue. */ | 555 | /* Subtract 1, if FIN was received */ |
| 557 | skb = skb_peek_tail(&sk->sk_receive_queue); | 556 | if (answ && sock_flag(sk, SOCK_DONE)) |
| 558 | if (answ && skb) | 557 | answ--; |
| 559 | answ -= tcp_hdr(skb)->fin; | ||
| 560 | } else | 558 | } else |
| 561 | answ = tp->urg_seq - tp->copied_seq; | 559 | answ = tp->urg_seq - tp->copied_seq; |
| 562 | release_sock(sk); | 560 | release_sock(sk); |
| @@ -1214,7 +1212,7 @@ new_segment: | |||
| 1214 | wait_for_sndbuf: | 1212 | wait_for_sndbuf: |
| 1215 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); | 1213 | set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); |
| 1216 | wait_for_memory: | 1214 | wait_for_memory: |
| 1217 | if (copied && likely(!tp->repair)) | 1215 | if (copied) |
| 1218 | tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); | 1216 | tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); |
| 1219 | 1217 | ||
| 1220 | if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) | 1218 | if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) |
| @@ -1225,7 +1223,7 @@ wait_for_memory: | |||
| 1225 | } | 1223 | } |
| 1226 | 1224 | ||
| 1227 | out: | 1225 | out: |
| 1228 | if (copied && likely(!tp->repair)) | 1226 | if (copied) |
| 1229 | tcp_push(sk, flags, mss_now, tp->nonagle); | 1227 | tcp_push(sk, flags, mss_now, tp->nonagle); |
| 1230 | release_sock(sk); | 1228 | release_sock(sk); |
| 1231 | return copied + copied_syn; | 1229 | return copied + copied_syn; |
| @@ -2766,6 +2764,8 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info) | |||
| 2766 | info->tcpi_options |= TCPI_OPT_ECN; | 2764 | info->tcpi_options |= TCPI_OPT_ECN; |
| 2767 | if (tp->ecn_flags & TCP_ECN_SEEN) | 2765 | if (tp->ecn_flags & TCP_ECN_SEEN) |
| 2768 | info->tcpi_options |= TCPI_OPT_ECN_SEEN; | 2766 | info->tcpi_options |= TCPI_OPT_ECN_SEEN; |
| 2767 | if (tp->syn_data_acked) | ||
| 2768 | info->tcpi_options |= TCPI_OPT_SYN_DATA; | ||
| 2769 | 2769 | ||
| 2770 | info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto); | 2770 | info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto); |
| 2771 | info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato); | 2771 | info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato); |
diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c index 813b43a76fec..834857f3c871 100644 --- a/net/ipv4/tcp_illinois.c +++ b/net/ipv4/tcp_illinois.c | |||
| @@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext, | |||
| 313 | .tcpv_rttcnt = ca->cnt_rtt, | 313 | .tcpv_rttcnt = ca->cnt_rtt, |
| 314 | .tcpv_minrtt = ca->base_rtt, | 314 | .tcpv_minrtt = ca->base_rtt, |
| 315 | }; | 315 | }; |
| 316 | u64 t = ca->sum_rtt; | ||
| 317 | 316 | ||
| 318 | do_div(t, ca->cnt_rtt); | 317 | if (info.tcpv_rttcnt > 0) { |
| 319 | info.tcpv_rtt = t; | 318 | u64 t = ca->sum_rtt; |
| 320 | 319 | ||
| 320 | do_div(t, info.tcpv_rttcnt); | ||
| 321 | info.tcpv_rtt = t; | ||
| 322 | } | ||
| 321 | nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); | 323 | nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info); |
| 322 | } | 324 | } |
| 323 | } | 325 | } |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 432c36649db3..609ff98aeb47 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -4529,6 +4529,9 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) | |||
| 4529 | struct tcphdr *th; | 4529 | struct tcphdr *th; |
| 4530 | bool fragstolen; | 4530 | bool fragstolen; |
| 4531 | 4531 | ||
| 4532 | if (size == 0) | ||
| 4533 | return 0; | ||
| 4534 | |||
| 4532 | skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); | 4535 | skb = alloc_skb(size + sizeof(*th), sk->sk_allocation); |
| 4533 | if (!skb) | 4536 | if (!skb) |
| 4534 | goto err; | 4537 | goto err; |
| @@ -5310,11 +5313,6 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, | |||
| 5310 | goto discard; | 5313 | goto discard; |
| 5311 | } | 5314 | } |
| 5312 | 5315 | ||
| 5313 | /* ts_recent update must be made after we are sure that the packet | ||
| 5314 | * is in window. | ||
| 5315 | */ | ||
| 5316 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
| 5317 | |||
| 5318 | /* step 3: check security and precedence [ignored] */ | 5316 | /* step 3: check security and precedence [ignored] */ |
| 5319 | 5317 | ||
| 5320 | /* step 4: Check for a SYN | 5318 | /* step 4: Check for a SYN |
| @@ -5549,6 +5547,11 @@ step5: | |||
| 5549 | if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) | 5547 | if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) |
| 5550 | goto discard; | 5548 | goto discard; |
| 5551 | 5549 | ||
| 5550 | /* ts_recent update must be made after we are sure that the packet | ||
| 5551 | * is in window. | ||
| 5552 | */ | ||
| 5553 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
| 5554 | |||
| 5552 | tcp_rcv_rtt_measure_ts(sk, skb); | 5555 | tcp_rcv_rtt_measure_ts(sk, skb); |
| 5553 | 5556 | ||
| 5554 | /* Process urgent data. */ | 5557 | /* Process urgent data. */ |
| @@ -5646,6 +5649,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
| 5646 | tcp_rearm_rto(sk); | 5649 | tcp_rearm_rto(sk); |
| 5647 | return true; | 5650 | return true; |
| 5648 | } | 5651 | } |
| 5652 | tp->syn_data_acked = tp->syn_data; | ||
| 5649 | return false; | 5653 | return false; |
| 5650 | } | 5654 | } |
| 5651 | 5655 | ||
| @@ -5963,7 +5967,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 5963 | 5967 | ||
| 5964 | req = tp->fastopen_rsk; | 5968 | req = tp->fastopen_rsk; |
| 5965 | if (req != NULL) { | 5969 | if (req != NULL) { |
| 5966 | BUG_ON(sk->sk_state != TCP_SYN_RECV && | 5970 | WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && |
| 5967 | sk->sk_state != TCP_FIN_WAIT1); | 5971 | sk->sk_state != TCP_FIN_WAIT1); |
| 5968 | 5972 | ||
| 5969 | if (tcp_check_req(sk, skb, req, NULL, true) == NULL) | 5973 | if (tcp_check_req(sk, skb, req, NULL, true) == NULL) |
| @@ -6052,7 +6056,15 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 6052 | * ACK we have received, this would have acknowledged | 6056 | * ACK we have received, this would have acknowledged |
| 6053 | * our SYNACK so stop the SYNACK timer. | 6057 | * our SYNACK so stop the SYNACK timer. |
| 6054 | */ | 6058 | */ |
| 6055 | if (acceptable && req != NULL) { | 6059 | if (req != NULL) { |
| 6060 | /* Return RST if ack_seq is invalid. | ||
| 6061 | * Note that RFC793 only says to generate a | ||
| 6062 | * DUPACK for it but for TCP Fast Open it seems | ||
| 6063 | * better to treat this case like TCP_SYN_RECV | ||
| 6064 | * above. | ||
| 6065 | */ | ||
| 6066 | if (!acceptable) | ||
| 6067 | return 1; | ||
| 6056 | /* We no longer need the request sock. */ | 6068 | /* We no longer need the request sock. */ |
| 6057 | reqsk_fastopen_remove(sk, req, false); | 6069 | reqsk_fastopen_remove(sk, req, false); |
| 6058 | tcp_rearm_rto(sk); | 6070 | tcp_rearm_rto(sk); |
| @@ -6118,6 +6130,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
| 6118 | } else | 6130 | } else |
| 6119 | goto discard; | 6131 | goto discard; |
| 6120 | 6132 | ||
| 6133 | /* ts_recent update must be made after we are sure that the packet | ||
| 6134 | * is in window. | ||
| 6135 | */ | ||
| 6136 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
| 6137 | |||
| 6121 | /* step 6: check the URG bit */ | 6138 | /* step 6: check the URG bit */ |
| 6122 | tcp_urg(sk, skb, th); | 6139 | tcp_urg(sk, skb, th); |
| 6123 | 6140 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ef998b008a57..0c4a64355603 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1461,6 +1461,7 @@ static int tcp_v4_conn_req_fastopen(struct sock *sk, | |||
| 1461 | skb_set_owner_r(skb, child); | 1461 | skb_set_owner_r(skb, child); |
| 1462 | __skb_queue_tail(&child->sk_receive_queue, skb); | 1462 | __skb_queue_tail(&child->sk_receive_queue, skb); |
| 1463 | tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; | 1463 | tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; |
| 1464 | tp->syn_data_acked = 1; | ||
| 1464 | } | 1465 | } |
| 1465 | sk->sk_data_ready(sk, 0); | 1466 | sk->sk_data_ready(sk, 0); |
| 1466 | bh_unlock_sock(child); | 1467 | bh_unlock_sock(child); |
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 4c752a6e0bcd..53bc5847bfa8 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c | |||
| @@ -864,7 +864,7 @@ static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr, | |||
| 864 | } | 864 | } |
| 865 | a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6]; | 865 | a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6]; |
| 866 | if (a) { | 866 | if (a) { |
| 867 | if (nla_len(a) != sizeof(sizeof(struct in6_addr))) | 867 | if (nla_len(a) != sizeof(struct in6_addr)) |
| 868 | return -EINVAL; | 868 | return -EINVAL; |
| 869 | addr->family = AF_INET6; | 869 | addr->family = AF_INET6; |
| 870 | memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6)); | 870 | memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6)); |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 27536ba16c9d..a7302d974f32 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
| @@ -510,6 +510,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
| 510 | newtp->rx_opt.mss_clamp = req->mss; | 510 | newtp->rx_opt.mss_clamp = req->mss; |
| 511 | TCP_ECN_openreq_child(newtp, req); | 511 | TCP_ECN_openreq_child(newtp, req); |
| 512 | newtp->fastopen_rsk = NULL; | 512 | newtp->fastopen_rsk = NULL; |
| 513 | newtp->syn_data_acked = 0; | ||
| 513 | 514 | ||
| 514 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS); | 515 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS); |
| 515 | } | 516 | } |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index cfe6ffe1c177..2798706cb063 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
| 1986 | tso_segs = tcp_init_tso_segs(sk, skb, mss_now); | 1986 | tso_segs = tcp_init_tso_segs(sk, skb, mss_now); |
| 1987 | BUG_ON(!tso_segs); | 1987 | BUG_ON(!tso_segs); |
| 1988 | 1988 | ||
| 1989 | if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE) | ||
| 1990 | goto repair; /* Skip network transmission */ | ||
| 1991 | |||
| 1989 | cwnd_quota = tcp_cwnd_test(tp, skb); | 1992 | cwnd_quota = tcp_cwnd_test(tp, skb); |
| 1990 | if (!cwnd_quota) | 1993 | if (!cwnd_quota) |
| 1991 | break; | 1994 | break; |
| @@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, | |||
| 2026 | if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) | 2029 | if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) |
| 2027 | break; | 2030 | break; |
| 2028 | 2031 | ||
| 2032 | repair: | ||
| 2029 | /* Advance the send_head. This one is sent out. | 2033 | /* Advance the send_head. This one is sent out. |
| 2030 | * This call will increment packets_out. | 2034 | * This call will increment packets_out. |
| 2031 | */ | 2035 | */ |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index fc04711e80c8..d47c1b4421a3 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
| @@ -347,8 +347,8 @@ void tcp_retransmit_timer(struct sock *sk) | |||
| 347 | return; | 347 | return; |
| 348 | } | 348 | } |
| 349 | if (tp->fastopen_rsk) { | 349 | if (tp->fastopen_rsk) { |
| 350 | BUG_ON(sk->sk_state != TCP_SYN_RECV && | 350 | WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && |
| 351 | sk->sk_state != TCP_FIN_WAIT1); | 351 | sk->sk_state != TCP_FIN_WAIT1); |
| 352 | tcp_fastopen_synack_timer(sk); | 352 | tcp_fastopen_synack_timer(sk); |
| 353 | /* Before we receive ACK to our SYN-ACK don't retransmit | 353 | /* Before we receive ACK to our SYN-ACK don't retransmit |
| 354 | * anything else (e.g., data or FIN segments). | 354 | * anything else (e.g., data or FIN segments). |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d7c56f8a5b4e..0424e4e27414 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -3064,14 +3064,15 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq, loff_t pos) | |||
| 3064 | struct hlist_node *n; | 3064 | struct hlist_node *n; |
| 3065 | hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket], | 3065 | hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket], |
| 3066 | addr_lst) { | 3066 | addr_lst) { |
| 3067 | if (!net_eq(dev_net(ifa->idev->dev), net)) | ||
| 3068 | continue; | ||
| 3067 | /* sync with offset */ | 3069 | /* sync with offset */ |
| 3068 | if (p < state->offset) { | 3070 | if (p < state->offset) { |
| 3069 | p++; | 3071 | p++; |
| 3070 | continue; | 3072 | continue; |
| 3071 | } | 3073 | } |
| 3072 | state->offset++; | 3074 | state->offset++; |
| 3073 | if (net_eq(dev_net(ifa->idev->dev), net)) | 3075 | return ifa; |
| 3074 | return ifa; | ||
| 3075 | } | 3076 | } |
| 3076 | 3077 | ||
| 3077 | /* prepare for next bucket */ | 3078 | /* prepare for next bucket */ |
| @@ -3089,18 +3090,20 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, | |||
| 3089 | struct hlist_node *n = &ifa->addr_lst; | 3090 | struct hlist_node *n = &ifa->addr_lst; |
| 3090 | 3091 | ||
| 3091 | hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst) { | 3092 | hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst) { |
| 3093 | if (!net_eq(dev_net(ifa->idev->dev), net)) | ||
| 3094 | continue; | ||
| 3092 | state->offset++; | 3095 | state->offset++; |
| 3093 | if (net_eq(dev_net(ifa->idev->dev), net)) | 3096 | return ifa; |
| 3094 | return ifa; | ||
| 3095 | } | 3097 | } |
| 3096 | 3098 | ||
| 3097 | while (++state->bucket < IN6_ADDR_HSIZE) { | 3099 | while (++state->bucket < IN6_ADDR_HSIZE) { |
| 3098 | state->offset = 0; | 3100 | state->offset = 0; |
| 3099 | hlist_for_each_entry_rcu_bh(ifa, n, | 3101 | hlist_for_each_entry_rcu_bh(ifa, n, |
| 3100 | &inet6_addr_lst[state->bucket], addr_lst) { | 3102 | &inet6_addr_lst[state->bucket], addr_lst) { |
| 3103 | if (!net_eq(dev_net(ifa->idev->dev), net)) | ||
| 3104 | continue; | ||
| 3101 | state->offset++; | 3105 | state->offset++; |
| 3102 | if (net_eq(dev_net(ifa->idev->dev), net)) | 3106 | return ifa; |
| 3103 | return ifa; | ||
| 3104 | } | 3107 | } |
| 3105 | } | 3108 | } |
| 3106 | 3109 | ||
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 0185679c5f53..d5cb3c4e66f8 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
| @@ -1633,9 +1633,9 @@ static size_t ip6gre_get_size(const struct net_device *dev) | |||
| 1633 | /* IFLA_GRE_OKEY */ | 1633 | /* IFLA_GRE_OKEY */ |
| 1634 | nla_total_size(4) + | 1634 | nla_total_size(4) + |
| 1635 | /* IFLA_GRE_LOCAL */ | 1635 | /* IFLA_GRE_LOCAL */ |
| 1636 | nla_total_size(4) + | 1636 | nla_total_size(sizeof(struct in6_addr)) + |
| 1637 | /* IFLA_GRE_REMOTE */ | 1637 | /* IFLA_GRE_REMOTE */ |
| 1638 | nla_total_size(4) + | 1638 | nla_total_size(sizeof(struct in6_addr)) + |
| 1639 | /* IFLA_GRE_TTL */ | 1639 | /* IFLA_GRE_TTL */ |
| 1640 | nla_total_size(1) + | 1640 | nla_total_size(1) + |
| 1641 | /* IFLA_GRE_TOS */ | 1641 | /* IFLA_GRE_TOS */ |
| @@ -1659,8 +1659,8 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev) | |||
| 1659 | nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || | 1659 | nla_put_be16(skb, IFLA_GRE_OFLAGS, p->o_flags) || |
| 1660 | nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || | 1660 | nla_put_be32(skb, IFLA_GRE_IKEY, p->i_key) || |
| 1661 | nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || | 1661 | nla_put_be32(skb, IFLA_GRE_OKEY, p->o_key) || |
| 1662 | nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->raddr) || | 1662 | nla_put(skb, IFLA_GRE_LOCAL, sizeof(struct in6_addr), &p->laddr) || |
| 1663 | nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->laddr) || | 1663 | nla_put(skb, IFLA_GRE_REMOTE, sizeof(struct in6_addr), &p->raddr) || |
| 1664 | nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || | 1664 | nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || |
| 1665 | /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ | 1665 | /*nla_put_u8(skb, IFLA_GRE_TOS, t->priority) ||*/ |
| 1666 | nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || | 1666 | nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ba6d13d1f1e1..e02faed6d17e 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
| @@ -827,6 +827,7 @@ pref_skip_coa: | |||
| 827 | if (val < 0 || val > 255) | 827 | if (val < 0 || val > 255) |
| 828 | goto e_inval; | 828 | goto e_inval; |
| 829 | np->min_hopcount = val; | 829 | np->min_hopcount = val; |
| 830 | retv = 0; | ||
| 830 | break; | 831 | break; |
| 831 | case IPV6_DONTFRAG: | 832 | case IPV6_DONTFRAG: |
| 832 | np->dontfrag = valbool; | 833 | np->dontfrag = valbool; |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index ff36194a71aa..2edce30ef733 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -535,7 +535,7 @@ static void ndisc_send_unsol_na(struct net_device *dev) | |||
| 535 | { | 535 | { |
| 536 | struct inet6_dev *idev; | 536 | struct inet6_dev *idev; |
| 537 | struct inet6_ifaddr *ifa; | 537 | struct inet6_ifaddr *ifa; |
| 538 | struct in6_addr mcaddr; | 538 | struct in6_addr mcaddr = IN6ADDR_LINKLOCAL_ALLNODES_INIT; |
| 539 | 539 | ||
| 540 | idev = in6_dev_get(dev); | 540 | idev = in6_dev_get(dev); |
| 541 | if (!idev) | 541 | if (!idev) |
| @@ -543,7 +543,6 @@ static void ndisc_send_unsol_na(struct net_device *dev) | |||
| 543 | 543 | ||
| 544 | read_lock_bh(&idev->lock); | 544 | read_lock_bh(&idev->lock); |
| 545 | list_for_each_entry(ifa, &idev->addr_list, if_list) { | 545 | list_for_each_entry(ifa, &idev->addr_list, if_list) { |
| 546 | addrconf_addr_solict_mult(&ifa->addr, &mcaddr); | ||
| 547 | ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, | 546 | ndisc_send_na(dev, NULL, &mcaddr, &ifa->addr, |
| 548 | /*router=*/ !!idev->cnf.forwarding, | 547 | /*router=*/ !!idev->cnf.forwarding, |
| 549 | /*solicited=*/ false, /*override=*/ true, | 548 | /*solicited=*/ false, /*override=*/ true, |
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c index e418bd6350a4..d57dab17a182 100644 --- a/net/ipv6/netfilter/ip6table_nat.c +++ b/net/ipv6/netfilter/ip6table_nat.c | |||
| @@ -186,7 +186,8 @@ nf_nat_ipv6_out(unsigned int hooknum, | |||
| 186 | 186 | ||
| 187 | if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, | 187 | if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3, |
| 188 | &ct->tuplehash[!dir].tuple.dst.u3) || | 188 | &ct->tuplehash[!dir].tuple.dst.u3) || |
| 189 | (ct->tuplehash[dir].tuple.src.u.all != | 189 | (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && |
| 190 | ct->tuplehash[dir].tuple.src.u.all != | ||
| 190 | ct->tuplehash[!dir].tuple.dst.u.all)) | 191 | ct->tuplehash[!dir].tuple.dst.u.all)) |
| 191 | if (nf_xfrm_me_harder(skb, AF_INET6) < 0) | 192 | if (nf_xfrm_me_harder(skb, AF_INET6) < 0) |
| 192 | ret = NF_DROP; | 193 | ret = NF_DROP; |
| @@ -222,6 +223,7 @@ nf_nat_ipv6_local_fn(unsigned int hooknum, | |||
| 222 | } | 223 | } |
| 223 | #ifdef CONFIG_XFRM | 224 | #ifdef CONFIG_XFRM |
| 224 | else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && | 225 | else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && |
| 226 | ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 && | ||
| 225 | ct->tuplehash[dir].tuple.dst.u.all != | 227 | ct->tuplehash[dir].tuple.dst.u.all != |
| 226 | ct->tuplehash[!dir].tuple.src.u.all) | 228 | ct->tuplehash[!dir].tuple.src.u.all) |
| 227 | if (nf_xfrm_me_harder(skb, AF_INET6)) | 229 | if (nf_xfrm_me_harder(skb, AF_INET6)) |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 18bd9bbbd1c6..22c8ea951185 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
| @@ -85,7 +85,7 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = { | |||
| 85 | { } | 85 | { } |
| 86 | }; | 86 | }; |
| 87 | 87 | ||
| 88 | static int __net_init nf_ct_frag6_sysctl_register(struct net *net) | 88 | static int nf_ct_frag6_sysctl_register(struct net *net) |
| 89 | { | 89 | { |
| 90 | struct ctl_table *table; | 90 | struct ctl_table *table; |
| 91 | struct ctl_table_header *hdr; | 91 | struct ctl_table_header *hdr; |
| @@ -127,7 +127,7 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net) | |||
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | #else | 129 | #else |
| 130 | static int __net_init nf_ct_frag6_sysctl_register(struct net *net) | 130 | static int nf_ct_frag6_sysctl_register(struct net *net) |
| 131 | { | 131 | { |
| 132 | return 0; | 132 | return 0; |
| 133 | } | 133 | } |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7c7e963260e1..b1e6cf0b95fd 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -219,7 +219,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { | |||
| 219 | }; | 219 | }; |
| 220 | 220 | ||
| 221 | static const u32 ip6_template_metrics[RTAX_MAX] = { | 221 | static const u32 ip6_template_metrics[RTAX_MAX] = { |
| 222 | [RTAX_HOPLIMIT - 1] = 255, | 222 | [RTAX_HOPLIMIT - 1] = 0, |
| 223 | }; | 223 | }; |
| 224 | 224 | ||
| 225 | static const struct rt6_info ip6_null_entry_template = { | 225 | static const struct rt6_info ip6_null_entry_template = { |
| @@ -1232,7 +1232,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
| 1232 | rt->rt6i_dst.addr = fl6->daddr; | 1232 | rt->rt6i_dst.addr = fl6->daddr; |
| 1233 | rt->rt6i_dst.plen = 128; | 1233 | rt->rt6i_dst.plen = 128; |
| 1234 | rt->rt6i_idev = idev; | 1234 | rt->rt6i_idev = idev; |
| 1235 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); | 1235 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 0); |
| 1236 | 1236 | ||
| 1237 | spin_lock_bh(&icmp6_dst_lock); | 1237 | spin_lock_bh(&icmp6_dst_lock); |
| 1238 | rt->dst.next = icmp6_dst_gc_list; | 1238 | rt->dst.next = icmp6_dst_gc_list; |
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 95a3a7a336ba..496ce2cebcd7 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
| @@ -421,6 +421,8 @@ static int ircomm_tty_install(struct tty_driver *driver, struct tty_struct *tty) | |||
| 421 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); | 421 | hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL); |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | tty->driver_data = self; | ||
| 425 | |||
| 424 | return tty_port_install(&self->port, driver, tty); | 426 | return tty_port_install(&self->port, driver, tty); |
| 425 | } | 427 | } |
| 426 | 428 | ||
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 37b8b8ba31f7..76125c57ee6d 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
| @@ -291,6 +291,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p | |||
| 291 | 291 | ||
| 292 | out_del_dev: | 292 | out_del_dev: |
| 293 | free_netdev(dev); | 293 | free_netdev(dev); |
| 294 | spriv->dev = NULL; | ||
| 294 | out_del_session: | 295 | out_del_session: |
| 295 | l2tp_session_delete(session); | 296 | l2tp_session_delete(session); |
| 296 | out: | 297 | out: |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 7e7198b51c06..c4ee43710aab 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
| @@ -2589,6 +2589,8 @@ __ip_vs_get_timeouts(struct net *net, struct ip_vs_timeout_user *u) | |||
| 2589 | struct ip_vs_proto_data *pd; | 2589 | struct ip_vs_proto_data *pd; |
| 2590 | #endif | 2590 | #endif |
| 2591 | 2591 | ||
| 2592 | memset(u, 0, sizeof (*u)); | ||
| 2593 | |||
| 2592 | #ifdef CONFIG_IP_VS_PROTO_TCP | 2594 | #ifdef CONFIG_IP_VS_PROTO_TCP |
| 2593 | pd = ip_vs_proto_data_get(net, IPPROTO_TCP); | 2595 | pd = ip_vs_proto_data_get(net, IPPROTO_TCP); |
| 2594 | u->tcp_timeout = pd->timeout_table[IP_VS_TCP_S_ESTABLISHED] / HZ; | 2596 | u->tcp_timeout = pd->timeout_table[IP_VS_TCP_S_ESTABLISHED] / HZ; |
| @@ -2766,7 +2768,6 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
| 2766 | { | 2768 | { |
| 2767 | struct ip_vs_timeout_user t; | 2769 | struct ip_vs_timeout_user t; |
| 2768 | 2770 | ||
| 2769 | memset(&t, 0, sizeof(t)); | ||
| 2770 | __ip_vs_get_timeouts(net, &t); | 2771 | __ip_vs_get_timeouts(net, &t); |
| 2771 | if (copy_to_user(user, &t, sizeof(t)) != 0) | 2772 | if (copy_to_user(user, &t, sizeof(t)) != 0) |
| 2772 | ret = -EFAULT; | 2773 | ret = -EFAULT; |
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 1b30b0dee708..962795e839ab 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c | |||
| @@ -753,7 +753,8 @@ static int callforward_do_filter(const union nf_inet_addr *src, | |||
| 753 | flowi4_to_flowi(&fl1), false)) { | 753 | flowi4_to_flowi(&fl1), false)) { |
| 754 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, | 754 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, |
| 755 | flowi4_to_flowi(&fl2), false)) { | 755 | flowi4_to_flowi(&fl2), false)) { |
| 756 | if (rt1->rt_gateway == rt2->rt_gateway && | 756 | if (rt_nexthop(rt1, fl1.daddr) == |
| 757 | rt_nexthop(rt2, fl2.daddr) && | ||
| 757 | rt1->dst.dev == rt2->dst.dev) | 758 | rt1->dst.dev == rt2->dst.dev) |
| 758 | ret = 1; | 759 | ret = 1; |
| 759 | dst_release(&rt2->dst); | 760 | dst_release(&rt2->dst); |
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 16c712563860..ae7f5daeee43 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c | |||
| @@ -180,9 +180,9 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, | |||
| 180 | typeof(nf_ct_timeout_find_get_hook) timeout_find_get; | 180 | typeof(nf_ct_timeout_find_get_hook) timeout_find_get; |
| 181 | struct ctnl_timeout *timeout; | 181 | struct ctnl_timeout *timeout; |
| 182 | struct nf_conn_timeout *timeout_ext; | 182 | struct nf_conn_timeout *timeout_ext; |
| 183 | const struct ipt_entry *e = par->entryinfo; | ||
| 184 | struct nf_conntrack_l4proto *l4proto; | 183 | struct nf_conntrack_l4proto *l4proto; |
| 185 | int ret = 0; | 184 | int ret = 0; |
| 185 | u8 proto; | ||
| 186 | 186 | ||
| 187 | rcu_read_lock(); | 187 | rcu_read_lock(); |
| 188 | timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook); | 188 | timeout_find_get = rcu_dereference(nf_ct_timeout_find_get_hook); |
| @@ -192,9 +192,11 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, | |||
| 192 | goto out; | 192 | goto out; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | if (e->ip.invflags & IPT_INV_PROTO) { | 195 | proto = xt_ct_find_proto(par); |
| 196 | if (!proto) { | ||
| 196 | ret = -EINVAL; | 197 | ret = -EINVAL; |
| 197 | pr_info("You cannot use inversion on L4 protocol\n"); | 198 | pr_info("You must specify a L4 protocol, and not use " |
| 199 | "inversions on it.\n"); | ||
| 198 | goto out; | 200 | goto out; |
| 199 | } | 201 | } |
| 200 | 202 | ||
| @@ -214,7 +216,7 @@ xt_ct_set_timeout(struct nf_conn *ct, const struct xt_tgchk_param *par, | |||
| 214 | /* Make sure the timeout policy matches any existing protocol tracker, | 216 | /* Make sure the timeout policy matches any existing protocol tracker, |
| 215 | * otherwise default to generic. | 217 | * otherwise default to generic. |
| 216 | */ | 218 | */ |
| 217 | l4proto = __nf_ct_l4proto_find(par->family, e->ip.proto); | 219 | l4proto = __nf_ct_l4proto_find(par->family, proto); |
| 218 | if (timeout->l4proto->l4proto != l4proto->l4proto) { | 220 | if (timeout->l4proto->l4proto != l4proto->l4proto) { |
| 219 | ret = -EINVAL; | 221 | ret = -EINVAL; |
| 220 | pr_info("Timeout policy `%s' can only be used by L4 protocol " | 222 | pr_info("Timeout policy `%s' can only be used by L4 protocol " |
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index ee2e5bc5a8c7..bd93e51d30ac 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c | |||
| @@ -70,6 +70,7 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info) | |||
| 70 | fl4.daddr = info->gw.ip; | 70 | fl4.daddr = info->gw.ip; |
| 71 | fl4.flowi4_tos = RT_TOS(iph->tos); | 71 | fl4.flowi4_tos = RT_TOS(iph->tos); |
| 72 | fl4.flowi4_scope = RT_SCOPE_UNIVERSE; | 72 | fl4.flowi4_scope = RT_SCOPE_UNIVERSE; |
| 73 | fl4.flowi4_flags = FLOWI_FLAG_KNOWN_NH; | ||
| 73 | rt = ip_route_output_key(net, &fl4); | 74 | rt = ip_route_output_key(net, &fl4); |
| 74 | if (IS_ERR(rt)) | 75 | if (IS_ERR(rt)) |
| 75 | return false; | 76 | return false; |
diff --git a/net/netfilter/xt_nat.c b/net/netfilter/xt_nat.c index 81aafa8e4fef..bea7464cc43f 100644 --- a/net/netfilter/xt_nat.c +++ b/net/netfilter/xt_nat.c | |||
| @@ -111,7 +111,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { | |||
| 111 | .family = NFPROTO_IPV4, | 111 | .family = NFPROTO_IPV4, |
| 112 | .table = "nat", | 112 | .table = "nat", |
| 113 | .hooks = (1 << NF_INET_POST_ROUTING) | | 113 | .hooks = (1 << NF_INET_POST_ROUTING) | |
| 114 | (1 << NF_INET_LOCAL_OUT), | 114 | (1 << NF_INET_LOCAL_IN), |
| 115 | .me = THIS_MODULE, | 115 | .me = THIS_MODULE, |
| 116 | }, | 116 | }, |
| 117 | { | 117 | { |
| @@ -123,7 +123,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { | |||
| 123 | .family = NFPROTO_IPV4, | 123 | .family = NFPROTO_IPV4, |
| 124 | .table = "nat", | 124 | .table = "nat", |
| 125 | .hooks = (1 << NF_INET_PRE_ROUTING) | | 125 | .hooks = (1 << NF_INET_PRE_ROUTING) | |
| 126 | (1 << NF_INET_LOCAL_IN), | 126 | (1 << NF_INET_LOCAL_OUT), |
| 127 | .me = THIS_MODULE, | 127 | .me = THIS_MODULE, |
| 128 | }, | 128 | }, |
| 129 | { | 129 | { |
| @@ -133,7 +133,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { | |||
| 133 | .targetsize = sizeof(struct nf_nat_range), | 133 | .targetsize = sizeof(struct nf_nat_range), |
| 134 | .table = "nat", | 134 | .table = "nat", |
| 135 | .hooks = (1 << NF_INET_POST_ROUTING) | | 135 | .hooks = (1 << NF_INET_POST_ROUTING) | |
| 136 | (1 << NF_INET_LOCAL_OUT), | 136 | (1 << NF_INET_LOCAL_IN), |
| 137 | .me = THIS_MODULE, | 137 | .me = THIS_MODULE, |
| 138 | }, | 138 | }, |
| 139 | { | 139 | { |
| @@ -143,7 +143,7 @@ static struct xt_target xt_nat_target_reg[] __read_mostly = { | |||
| 143 | .targetsize = sizeof(struct nf_nat_range), | 143 | .targetsize = sizeof(struct nf_nat_range), |
| 144 | .table = "nat", | 144 | .table = "nat", |
| 145 | .hooks = (1 << NF_INET_PRE_ROUTING) | | 145 | .hooks = (1 << NF_INET_PRE_ROUTING) | |
| 146 | (1 << NF_INET_LOCAL_IN), | 146 | (1 << NF_INET_LOCAL_OUT), |
| 147 | .me = THIS_MODULE, | 147 | .me = THIS_MODULE, |
| 148 | }, | 148 | }, |
| 149 | }; | 149 | }; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 01e944a017a4..4da797fa5ec5 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -138,6 +138,8 @@ static int netlink_dump(struct sock *sk); | |||
| 138 | static DEFINE_RWLOCK(nl_table_lock); | 138 | static DEFINE_RWLOCK(nl_table_lock); |
| 139 | static atomic_t nl_table_users = ATOMIC_INIT(0); | 139 | static atomic_t nl_table_users = ATOMIC_INIT(0); |
| 140 | 140 | ||
| 141 | #define nl_deref_protected(X) rcu_dereference_protected(X, lockdep_is_held(&nl_table_lock)); | ||
| 142 | |||
| 141 | static ATOMIC_NOTIFIER_HEAD(netlink_chain); | 143 | static ATOMIC_NOTIFIER_HEAD(netlink_chain); |
| 142 | 144 | ||
| 143 | static inline u32 netlink_group_mask(u32 group) | 145 | static inline u32 netlink_group_mask(u32 group) |
| @@ -345,6 +347,11 @@ netlink_update_listeners(struct sock *sk) | |||
| 345 | struct hlist_node *node; | 347 | struct hlist_node *node; |
| 346 | unsigned long mask; | 348 | unsigned long mask; |
| 347 | unsigned int i; | 349 | unsigned int i; |
| 350 | struct listeners *listeners; | ||
| 351 | |||
| 352 | listeners = nl_deref_protected(tbl->listeners); | ||
| 353 | if (!listeners) | ||
| 354 | return; | ||
| 348 | 355 | ||
| 349 | for (i = 0; i < NLGRPLONGS(tbl->groups); i++) { | 356 | for (i = 0; i < NLGRPLONGS(tbl->groups); i++) { |
| 350 | mask = 0; | 357 | mask = 0; |
| @@ -352,7 +359,7 @@ netlink_update_listeners(struct sock *sk) | |||
| 352 | if (i < NLGRPLONGS(nlk_sk(sk)->ngroups)) | 359 | if (i < NLGRPLONGS(nlk_sk(sk)->ngroups)) |
| 353 | mask |= nlk_sk(sk)->groups[i]; | 360 | mask |= nlk_sk(sk)->groups[i]; |
| 354 | } | 361 | } |
| 355 | tbl->listeners->masks[i] = mask; | 362 | listeners->masks[i] = mask; |
| 356 | } | 363 | } |
| 357 | /* this function is only called with the netlink table "grabbed", which | 364 | /* this function is only called with the netlink table "grabbed", which |
| 358 | * makes sure updates are visible before bind or setsockopt return. */ | 365 | * makes sure updates are visible before bind or setsockopt return. */ |
| @@ -536,7 +543,11 @@ static int netlink_release(struct socket *sock) | |||
| 536 | if (netlink_is_kernel(sk)) { | 543 | if (netlink_is_kernel(sk)) { |
| 537 | BUG_ON(nl_table[sk->sk_protocol].registered == 0); | 544 | BUG_ON(nl_table[sk->sk_protocol].registered == 0); |
| 538 | if (--nl_table[sk->sk_protocol].registered == 0) { | 545 | if (--nl_table[sk->sk_protocol].registered == 0) { |
| 539 | kfree(nl_table[sk->sk_protocol].listeners); | 546 | struct listeners *old; |
| 547 | |||
| 548 | old = nl_deref_protected(nl_table[sk->sk_protocol].listeners); | ||
| 549 | RCU_INIT_POINTER(nl_table[sk->sk_protocol].listeners, NULL); | ||
| 550 | kfree_rcu(old, rcu); | ||
| 540 | nl_table[sk->sk_protocol].module = NULL; | 551 | nl_table[sk->sk_protocol].module = NULL; |
| 541 | nl_table[sk->sk_protocol].bind = NULL; | 552 | nl_table[sk->sk_protocol].bind = NULL; |
| 542 | nl_table[sk->sk_protocol].flags = 0; | 553 | nl_table[sk->sk_protocol].flags = 0; |
| @@ -982,7 +993,7 @@ int netlink_has_listeners(struct sock *sk, unsigned int group) | |||
| 982 | rcu_read_lock(); | 993 | rcu_read_lock(); |
| 983 | listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners); | 994 | listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners); |
| 984 | 995 | ||
| 985 | if (group - 1 < nl_table[sk->sk_protocol].groups) | 996 | if (listeners && group - 1 < nl_table[sk->sk_protocol].groups) |
| 986 | res = test_bit(group - 1, listeners->masks); | 997 | res = test_bit(group - 1, listeners->masks); |
| 987 | 998 | ||
| 988 | rcu_read_unlock(); | 999 | rcu_read_unlock(); |
| @@ -1625,7 +1636,7 @@ int __netlink_change_ngroups(struct sock *sk, unsigned int groups) | |||
| 1625 | new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC); | 1636 | new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC); |
| 1626 | if (!new) | 1637 | if (!new) |
| 1627 | return -ENOMEM; | 1638 | return -ENOMEM; |
| 1628 | old = rcu_dereference_protected(tbl->listeners, 1); | 1639 | old = nl_deref_protected(tbl->listeners); |
| 1629 | memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups)); | 1640 | memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups)); |
| 1630 | rcu_assign_pointer(tbl->listeners, new); | 1641 | rcu_assign_pointer(tbl->listeners, new); |
| 1631 | 1642 | ||
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index f0dd83cff906..9687fa1c2275 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c | |||
| @@ -84,18 +84,19 @@ | |||
| 84 | * grp->index is the index of the group; and grp->slot_shift | 84 | * grp->index is the index of the group; and grp->slot_shift |
| 85 | * is the shift for the corresponding (scaled) sigma_i. | 85 | * is the shift for the corresponding (scaled) sigma_i. |
| 86 | */ | 86 | */ |
| 87 | #define QFQ_MAX_INDEX 19 | 87 | #define QFQ_MAX_INDEX 24 |
| 88 | #define QFQ_MAX_WSHIFT 16 | 88 | #define QFQ_MAX_WSHIFT 12 |
| 89 | 89 | ||
| 90 | #define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT) | 90 | #define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT) |
| 91 | #define QFQ_MAX_WSUM (2*QFQ_MAX_WEIGHT) | 91 | #define QFQ_MAX_WSUM (16*QFQ_MAX_WEIGHT) |
| 92 | 92 | ||
| 93 | #define FRAC_BITS 30 /* fixed point arithmetic */ | 93 | #define FRAC_BITS 30 /* fixed point arithmetic */ |
| 94 | #define ONE_FP (1UL << FRAC_BITS) | 94 | #define ONE_FP (1UL << FRAC_BITS) |
| 95 | #define IWSUM (ONE_FP/QFQ_MAX_WSUM) | 95 | #define IWSUM (ONE_FP/QFQ_MAX_WSUM) |
| 96 | 96 | ||
| 97 | #define QFQ_MTU_SHIFT 11 | 97 | #define QFQ_MTU_SHIFT 16 /* to support TSO/GSO */ |
| 98 | #define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX) | 98 | #define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX) |
| 99 | #define QFQ_MIN_LMAX 256 /* min possible lmax for a class */ | ||
| 99 | 100 | ||
| 100 | /* | 101 | /* |
| 101 | * Possible group states. These values are used as indexes for the bitmaps | 102 | * Possible group states. These values are used as indexes for the bitmaps |
| @@ -231,6 +232,32 @@ static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl, | |||
| 231 | q->wsum += delta_w; | 232 | q->wsum += delta_w; |
| 232 | } | 233 | } |
| 233 | 234 | ||
| 235 | static void qfq_update_reactivate_class(struct qfq_sched *q, | ||
| 236 | struct qfq_class *cl, | ||
| 237 | u32 inv_w, u32 lmax, int delta_w) | ||
| 238 | { | ||
| 239 | bool need_reactivation = false; | ||
| 240 | int i = qfq_calc_index(inv_w, lmax); | ||
| 241 | |||
| 242 | if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { | ||
| 243 | /* | ||
| 244 | * shift cl->F back, to not charge the | ||
| 245 | * class for the not-yet-served head | ||
| 246 | * packet | ||
| 247 | */ | ||
| 248 | cl->F = cl->S; | ||
| 249 | /* remove class from its slot in the old group */ | ||
| 250 | qfq_deactivate_class(q, cl); | ||
| 251 | need_reactivation = true; | ||
| 252 | } | ||
| 253 | |||
| 254 | qfq_update_class_params(q, cl, lmax, inv_w, delta_w); | ||
| 255 | |||
| 256 | if (need_reactivation) /* activate in new group */ | ||
| 257 | qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); | ||
| 258 | } | ||
| 259 | |||
| 260 | |||
| 234 | static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | 261 | static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, |
| 235 | struct nlattr **tca, unsigned long *arg) | 262 | struct nlattr **tca, unsigned long *arg) |
| 236 | { | 263 | { |
| @@ -238,7 +265,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
| 238 | struct qfq_class *cl = (struct qfq_class *)*arg; | 265 | struct qfq_class *cl = (struct qfq_class *)*arg; |
| 239 | struct nlattr *tb[TCA_QFQ_MAX + 1]; | 266 | struct nlattr *tb[TCA_QFQ_MAX + 1]; |
| 240 | u32 weight, lmax, inv_w; | 267 | u32 weight, lmax, inv_w; |
| 241 | int i, err; | 268 | int err; |
| 242 | int delta_w; | 269 | int delta_w; |
| 243 | 270 | ||
| 244 | if (tca[TCA_OPTIONS] == NULL) { | 271 | if (tca[TCA_OPTIONS] == NULL) { |
| @@ -270,16 +297,14 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
| 270 | 297 | ||
| 271 | if (tb[TCA_QFQ_LMAX]) { | 298 | if (tb[TCA_QFQ_LMAX]) { |
| 272 | lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); | 299 | lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); |
| 273 | if (!lmax || lmax > (1UL << QFQ_MTU_SHIFT)) { | 300 | if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) { |
| 274 | pr_notice("qfq: invalid max length %u\n", lmax); | 301 | pr_notice("qfq: invalid max length %u\n", lmax); |
| 275 | return -EINVAL; | 302 | return -EINVAL; |
| 276 | } | 303 | } |
| 277 | } else | 304 | } else |
| 278 | lmax = 1UL << QFQ_MTU_SHIFT; | 305 | lmax = psched_mtu(qdisc_dev(sch)); |
| 279 | 306 | ||
| 280 | if (cl != NULL) { | 307 | if (cl != NULL) { |
| 281 | bool need_reactivation = false; | ||
| 282 | |||
| 283 | if (tca[TCA_RATE]) { | 308 | if (tca[TCA_RATE]) { |
| 284 | err = gen_replace_estimator(&cl->bstats, &cl->rate_est, | 309 | err = gen_replace_estimator(&cl->bstats, &cl->rate_est, |
| 285 | qdisc_root_sleeping_lock(sch), | 310 | qdisc_root_sleeping_lock(sch), |
| @@ -291,24 +316,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
| 291 | if (lmax == cl->lmax && inv_w == cl->inv_w) | 316 | if (lmax == cl->lmax && inv_w == cl->inv_w) |
| 292 | return 0; /* nothing to update */ | 317 | return 0; /* nothing to update */ |
| 293 | 318 | ||
| 294 | i = qfq_calc_index(inv_w, lmax); | ||
| 295 | sch_tree_lock(sch); | 319 | sch_tree_lock(sch); |
| 296 | if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { | 320 | qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w); |
| 297 | /* | ||
| 298 | * shift cl->F back, to not charge the | ||
| 299 | * class for the not-yet-served head | ||
| 300 | * packet | ||
| 301 | */ | ||
| 302 | cl->F = cl->S; | ||
| 303 | /* remove class from its slot in the old group */ | ||
| 304 | qfq_deactivate_class(q, cl); | ||
| 305 | need_reactivation = true; | ||
| 306 | } | ||
| 307 | |||
| 308 | qfq_update_class_params(q, cl, lmax, inv_w, delta_w); | ||
| 309 | |||
| 310 | if (need_reactivation) /* activate in new group */ | ||
| 311 | qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); | ||
| 312 | sch_tree_unlock(sch); | 321 | sch_tree_unlock(sch); |
| 313 | 322 | ||
| 314 | return 0; | 323 | return 0; |
| @@ -663,15 +672,48 @@ static void qfq_make_eligible(struct qfq_sched *q, u64 old_V) | |||
| 663 | 672 | ||
| 664 | 673 | ||
| 665 | /* | 674 | /* |
| 666 | * XXX we should make sure that slot becomes less than 32. | 675 | * If the weight and lmax (max_pkt_size) of the classes do not change, |
| 667 | * This is guaranteed by the input values. | 676 | * then QFQ guarantees that the slot index is never higher than |
| 668 | * roundedS is always cl->S rounded on grp->slot_shift bits. | 677 | * 2 + ((1<<QFQ_MTU_SHIFT)/QFQ_MIN_LMAX) * (QFQ_MAX_WEIGHT/QFQ_MAX_WSUM). |
| 678 | * | ||
| 679 | * With the current values of the above constants, the index is | ||
| 680 | * then guaranteed to never be higher than 2 + 256 * (1 / 16) = 18. | ||
| 681 | * | ||
| 682 | * When the weight of a class is increased or the lmax of the class is | ||
| 683 | * decreased, a new class with smaller slot size may happen to be | ||
| 684 | * activated. The activation of this class should be properly delayed | ||
| 685 | * to when the service of the class has finished in the ideal system | ||
| 686 | * tracked by QFQ. If the activation of the class is not delayed to | ||
| 687 | * this reference time instant, then this class may be unjustly served | ||
| 688 | * before other classes waiting for service. This may cause | ||
| 689 | * (unfrequently) the above bound to the slot index to be violated for | ||
| 690 | * some of these unlucky classes. | ||
| 691 | * | ||
| 692 | * Instead of delaying the activation of the new class, which is quite | ||
| 693 | * complex, the following inaccurate but simple solution is used: if | ||
| 694 | * the slot index is higher than QFQ_MAX_SLOTS-2, then the timestamps | ||
| 695 | * of the class are shifted backward so as to let the slot index | ||
| 696 | * become equal to QFQ_MAX_SLOTS-2. This threshold is used because, if | ||
| 697 | * the slot index is above it, then the data structure implementing | ||
| 698 | * the bucket list either gets immediately corrupted or may get | ||
| 699 | * corrupted on a possible next packet arrival that causes the start | ||
| 700 | * time of the group to be shifted backward. | ||
| 669 | */ | 701 | */ |
| 670 | static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, | 702 | static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, |
| 671 | u64 roundedS) | 703 | u64 roundedS) |
| 672 | { | 704 | { |
| 673 | u64 slot = (roundedS - grp->S) >> grp->slot_shift; | 705 | u64 slot = (roundedS - grp->S) >> grp->slot_shift; |
| 674 | unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS; | 706 | unsigned int i; /* slot index in the bucket list */ |
| 707 | |||
| 708 | if (unlikely(slot > QFQ_MAX_SLOTS - 2)) { | ||
| 709 | u64 deltaS = roundedS - grp->S - | ||
| 710 | ((u64)(QFQ_MAX_SLOTS - 2)<<grp->slot_shift); | ||
| 711 | cl->S -= deltaS; | ||
| 712 | cl->F -= deltaS; | ||
| 713 | slot = QFQ_MAX_SLOTS - 2; | ||
| 714 | } | ||
| 715 | |||
| 716 | i = (grp->front + slot) % QFQ_MAX_SLOTS; | ||
| 675 | 717 | ||
| 676 | hlist_add_head(&cl->next, &grp->slots[i]); | 718 | hlist_add_head(&cl->next, &grp->slots[i]); |
| 677 | __set_bit(slot, &grp->full_slots); | 719 | __set_bit(slot, &grp->full_slots); |
| @@ -892,6 +934,13 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 892 | } | 934 | } |
| 893 | pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); | 935 | pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); |
| 894 | 936 | ||
| 937 | if (unlikely(cl->lmax < qdisc_pkt_len(skb))) { | ||
| 938 | pr_debug("qfq: increasing maxpkt from %u to %u for class %u", | ||
| 939 | cl->lmax, qdisc_pkt_len(skb), cl->common.classid); | ||
| 940 | qfq_update_reactivate_class(q, cl, cl->inv_w, | ||
| 941 | qdisc_pkt_len(skb), 0); | ||
| 942 | } | ||
| 943 | |||
| 895 | err = qdisc_enqueue(skb, cl->qdisc); | 944 | err = qdisc_enqueue(skb, cl->qdisc); |
| 896 | if (unlikely(err != NET_XMIT_SUCCESS)) { | 945 | if (unlikely(err != NET_XMIT_SUCCESS)) { |
| 897 | pr_debug("qfq_enqueue: enqueue failed %d\n", err); | 946 | pr_debug("qfq_enqueue: enqueue failed %d\n", err); |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index c3bea269faf4..9966e7b16451 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
| @@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = { | |||
| 102 | .open = sctp_snmp_seq_open, | 102 | .open = sctp_snmp_seq_open, |
| 103 | .read = seq_read, | 103 | .read = seq_read, |
| 104 | .llseek = seq_lseek, | 104 | .llseek = seq_lseek, |
| 105 | .release = single_release, | 105 | .release = single_release_net, |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | /* Set up the proc fs entry for 'snmp' object. */ | 108 | /* Set up the proc fs entry for 'snmp' object. */ |
| @@ -251,7 +251,7 @@ static const struct file_operations sctp_eps_seq_fops = { | |||
| 251 | .open = sctp_eps_seq_open, | 251 | .open = sctp_eps_seq_open, |
| 252 | .read = seq_read, | 252 | .read = seq_read, |
| 253 | .llseek = seq_lseek, | 253 | .llseek = seq_lseek, |
| 254 | .release = seq_release, | 254 | .release = seq_release_net, |
| 255 | }; | 255 | }; |
| 256 | 256 | ||
| 257 | /* Set up the proc fs entry for 'eps' object. */ | 257 | /* Set up the proc fs entry for 'eps' object. */ |
| @@ -372,7 +372,7 @@ static const struct file_operations sctp_assocs_seq_fops = { | |||
| 372 | .open = sctp_assocs_seq_open, | 372 | .open = sctp_assocs_seq_open, |
| 373 | .read = seq_read, | 373 | .read = seq_read, |
| 374 | .llseek = seq_lseek, | 374 | .llseek = seq_lseek, |
| 375 | .release = seq_release, | 375 | .release = seq_release_net, |
| 376 | }; | 376 | }; |
| 377 | 377 | ||
| 378 | /* Set up the proc fs entry for 'assocs' object. */ | 378 | /* Set up the proc fs entry for 'assocs' object. */ |
| @@ -517,7 +517,7 @@ static const struct file_operations sctp_remaddr_seq_fops = { | |||
| 517 | .open = sctp_remaddr_seq_open, | 517 | .open = sctp_remaddr_seq_open, |
| 518 | .read = seq_read, | 518 | .read = seq_read, |
| 519 | .llseek = seq_lseek, | 519 | .llseek = seq_lseek, |
| 520 | .release = seq_release, | 520 | .release = seq_release_net, |
| 521 | }; | 521 | }; |
| 522 | 522 | ||
| 523 | int __net_init sctp_remaddr_proc_init(struct net *net) | 523 | int __net_init sctp_remaddr_proc_init(struct net *net) |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 57f7de839b03..6773d7803627 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -1642,8 +1642,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
| 1642 | asoc->outqueue.outstanding_bytes; | 1642 | asoc->outqueue.outstanding_bytes; |
| 1643 | sackh.num_gap_ack_blocks = 0; | 1643 | sackh.num_gap_ack_blocks = 0; |
| 1644 | sackh.num_dup_tsns = 0; | 1644 | sackh.num_dup_tsns = 0; |
| 1645 | chunk->subh.sack_hdr = &sackh; | ||
| 1645 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, | 1646 | sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK, |
| 1646 | SCTP_SACKH(&sackh)); | 1647 | SCTP_CHUNK(chunk)); |
| 1647 | break; | 1648 | break; |
| 1648 | 1649 | ||
| 1649 | case SCTP_CMD_DISCARD_PACKET: | 1650 | case SCTP_CMD_DISCARD_PACKET: |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 59d16ea927f0..a60d1f8b41c5 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -974,7 +974,7 @@ SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk, | |||
| 974 | void *addr_buf; | 974 | void *addr_buf; |
| 975 | struct sctp_af *af; | 975 | struct sctp_af *af; |
| 976 | 976 | ||
| 977 | SCTP_DEBUG_PRINTK("sctp_setsocktopt_bindx: sk %p addrs %p" | 977 | SCTP_DEBUG_PRINTK("sctp_setsockopt_bindx: sk %p addrs %p" |
| 978 | " addrs_size %d opt %d\n", sk, addrs, addrs_size, op); | 978 | " addrs_size %d opt %d\n", sk, addrs, addrs_size, op); |
| 979 | 979 | ||
| 980 | if (unlikely(addrs_size <= 0)) | 980 | if (unlikely(addrs_size <= 0)) |
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 5a3d675d2f2f..a9c0bbccad6b 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c | |||
| @@ -172,7 +172,7 @@ out_free: | |||
| 172 | xprt_free_allocation(req); | 172 | xprt_free_allocation(req); |
| 173 | 173 | ||
| 174 | dprintk("RPC: setup backchannel transport failed\n"); | 174 | dprintk("RPC: setup backchannel transport failed\n"); |
| 175 | return -1; | 175 | return -ENOMEM; |
| 176 | } | 176 | } |
| 177 | EXPORT_SYMBOL_GPL(xprt_setup_backchannel); | 177 | EXPORT_SYMBOL_GPL(xprt_setup_backchannel); |
| 178 | 178 | ||
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 2a68bb3db772..fc2f7aa4dca7 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
| @@ -1409,11 +1409,11 @@ static ssize_t read_flush(struct file *file, char __user *buf, | |||
| 1409 | size_t count, loff_t *ppos, | 1409 | size_t count, loff_t *ppos, |
| 1410 | struct cache_detail *cd) | 1410 | struct cache_detail *cd) |
| 1411 | { | 1411 | { |
| 1412 | char tbuf[20]; | 1412 | char tbuf[22]; |
| 1413 | unsigned long p = *ppos; | 1413 | unsigned long p = *ppos; |
| 1414 | size_t len; | 1414 | size_t len; |
| 1415 | 1415 | ||
| 1416 | sprintf(tbuf, "%lu\n", convert_to_wallclock(cd->flush_time)); | 1416 | snprintf(tbuf, sizeof(tbuf), "%lu\n", convert_to_wallclock(cd->flush_time)); |
| 1417 | len = strlen(tbuf); | 1417 | len = strlen(tbuf); |
| 1418 | if (p >= len) | 1418 | if (p >= len) |
| 1419 | return 0; | 1419 | return 0; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index aaaadfbe36e9..75853cabf4c9 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -254,7 +254,6 @@ struct sock_xprt { | |||
| 254 | void (*old_data_ready)(struct sock *, int); | 254 | void (*old_data_ready)(struct sock *, int); |
| 255 | void (*old_state_change)(struct sock *); | 255 | void (*old_state_change)(struct sock *); |
| 256 | void (*old_write_space)(struct sock *); | 256 | void (*old_write_space)(struct sock *); |
| 257 | void (*old_error_report)(struct sock *); | ||
| 258 | }; | 257 | }; |
| 259 | 258 | ||
| 260 | /* | 259 | /* |
| @@ -737,10 +736,10 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
| 737 | dprintk("RPC: sendmsg returned unrecognized error %d\n", | 736 | dprintk("RPC: sendmsg returned unrecognized error %d\n", |
| 738 | -status); | 737 | -status); |
| 739 | case -ECONNRESET: | 738 | case -ECONNRESET: |
| 740 | case -EPIPE: | ||
| 741 | xs_tcp_shutdown(xprt); | 739 | xs_tcp_shutdown(xprt); |
| 742 | case -ECONNREFUSED: | 740 | case -ECONNREFUSED: |
| 743 | case -ENOTCONN: | 741 | case -ENOTCONN: |
| 742 | case -EPIPE: | ||
| 744 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); | 743 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); |
| 745 | } | 744 | } |
| 746 | 745 | ||
| @@ -781,7 +780,6 @@ static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk) | |||
| 781 | transport->old_data_ready = sk->sk_data_ready; | 780 | transport->old_data_ready = sk->sk_data_ready; |
| 782 | transport->old_state_change = sk->sk_state_change; | 781 | transport->old_state_change = sk->sk_state_change; |
| 783 | transport->old_write_space = sk->sk_write_space; | 782 | transport->old_write_space = sk->sk_write_space; |
| 784 | transport->old_error_report = sk->sk_error_report; | ||
| 785 | } | 783 | } |
| 786 | 784 | ||
| 787 | static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk) | 785 | static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk) |
| @@ -789,7 +787,6 @@ static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *s | |||
| 789 | sk->sk_data_ready = transport->old_data_ready; | 787 | sk->sk_data_ready = transport->old_data_ready; |
| 790 | sk->sk_state_change = transport->old_state_change; | 788 | sk->sk_state_change = transport->old_state_change; |
| 791 | sk->sk_write_space = transport->old_write_space; | 789 | sk->sk_write_space = transport->old_write_space; |
| 792 | sk->sk_error_report = transport->old_error_report; | ||
| 793 | } | 790 | } |
| 794 | 791 | ||
| 795 | static void xs_reset_transport(struct sock_xprt *transport) | 792 | static void xs_reset_transport(struct sock_xprt *transport) |
| @@ -1453,7 +1450,7 @@ static void xs_tcp_cancel_linger_timeout(struct rpc_xprt *xprt) | |||
| 1453 | xprt_clear_connecting(xprt); | 1450 | xprt_clear_connecting(xprt); |
| 1454 | } | 1451 | } |
| 1455 | 1452 | ||
| 1456 | static void xs_sock_mark_closed(struct rpc_xprt *xprt) | 1453 | static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt) |
| 1457 | { | 1454 | { |
| 1458 | smp_mb__before_clear_bit(); | 1455 | smp_mb__before_clear_bit(); |
| 1459 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); | 1456 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); |
| @@ -1461,6 +1458,11 @@ static void xs_sock_mark_closed(struct rpc_xprt *xprt) | |||
| 1461 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); | 1458 | clear_bit(XPRT_CLOSE_WAIT, &xprt->state); |
| 1462 | clear_bit(XPRT_CLOSING, &xprt->state); | 1459 | clear_bit(XPRT_CLOSING, &xprt->state); |
| 1463 | smp_mb__after_clear_bit(); | 1460 | smp_mb__after_clear_bit(); |
| 1461 | } | ||
| 1462 | |||
| 1463 | static void xs_sock_mark_closed(struct rpc_xprt *xprt) | ||
| 1464 | { | ||
| 1465 | xs_sock_reset_connection_flags(xprt); | ||
| 1464 | /* Mark transport as closed and wake up all pending tasks */ | 1466 | /* Mark transport as closed and wake up all pending tasks */ |
| 1465 | xprt_disconnect_done(xprt); | 1467 | xprt_disconnect_done(xprt); |
| 1466 | } | 1468 | } |
| @@ -1516,6 +1518,7 @@ static void xs_tcp_state_change(struct sock *sk) | |||
| 1516 | case TCP_CLOSE_WAIT: | 1518 | case TCP_CLOSE_WAIT: |
| 1517 | /* The server initiated a shutdown of the socket */ | 1519 | /* The server initiated a shutdown of the socket */ |
| 1518 | xprt->connect_cookie++; | 1520 | xprt->connect_cookie++; |
| 1521 | clear_bit(XPRT_CONNECTED, &xprt->state); | ||
| 1519 | xs_tcp_force_close(xprt); | 1522 | xs_tcp_force_close(xprt); |
| 1520 | case TCP_CLOSING: | 1523 | case TCP_CLOSING: |
| 1521 | /* | 1524 | /* |
| @@ -1540,25 +1543,6 @@ static void xs_tcp_state_change(struct sock *sk) | |||
| 1540 | read_unlock_bh(&sk->sk_callback_lock); | 1543 | read_unlock_bh(&sk->sk_callback_lock); |
| 1541 | } | 1544 | } |
| 1542 | 1545 | ||
| 1543 | /** | ||
| 1544 | * xs_error_report - callback mainly for catching socket errors | ||
| 1545 | * @sk: socket | ||
| 1546 | */ | ||
| 1547 | static void xs_error_report(struct sock *sk) | ||
| 1548 | { | ||
| 1549 | struct rpc_xprt *xprt; | ||
| 1550 | |||
| 1551 | read_lock_bh(&sk->sk_callback_lock); | ||
| 1552 | if (!(xprt = xprt_from_sock(sk))) | ||
| 1553 | goto out; | ||
| 1554 | dprintk("RPC: %s client %p...\n" | ||
| 1555 | "RPC: error %d\n", | ||
| 1556 | __func__, xprt, sk->sk_err); | ||
| 1557 | xprt_wake_pending_tasks(xprt, -EAGAIN); | ||
| 1558 | out: | ||
| 1559 | read_unlock_bh(&sk->sk_callback_lock); | ||
| 1560 | } | ||
| 1561 | |||
| 1562 | static void xs_write_space(struct sock *sk) | 1546 | static void xs_write_space(struct sock *sk) |
| 1563 | { | 1547 | { |
| 1564 | struct socket *sock; | 1548 | struct socket *sock; |
| @@ -1858,7 +1842,6 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt, | |||
| 1858 | sk->sk_user_data = xprt; | 1842 | sk->sk_user_data = xprt; |
| 1859 | sk->sk_data_ready = xs_local_data_ready; | 1843 | sk->sk_data_ready = xs_local_data_ready; |
| 1860 | sk->sk_write_space = xs_udp_write_space; | 1844 | sk->sk_write_space = xs_udp_write_space; |
| 1861 | sk->sk_error_report = xs_error_report; | ||
| 1862 | sk->sk_allocation = GFP_ATOMIC; | 1845 | sk->sk_allocation = GFP_ATOMIC; |
| 1863 | 1846 | ||
| 1864 | xprt_clear_connected(xprt); | 1847 | xprt_clear_connected(xprt); |
| @@ -1983,7 +1966,6 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
| 1983 | sk->sk_user_data = xprt; | 1966 | sk->sk_user_data = xprt; |
| 1984 | sk->sk_data_ready = xs_udp_data_ready; | 1967 | sk->sk_data_ready = xs_udp_data_ready; |
| 1985 | sk->sk_write_space = xs_udp_write_space; | 1968 | sk->sk_write_space = xs_udp_write_space; |
| 1986 | sk->sk_error_report = xs_error_report; | ||
| 1987 | sk->sk_no_check = UDP_CSUM_NORCV; | 1969 | sk->sk_no_check = UDP_CSUM_NORCV; |
| 1988 | sk->sk_allocation = GFP_ATOMIC; | 1970 | sk->sk_allocation = GFP_ATOMIC; |
| 1989 | 1971 | ||
| @@ -2050,10 +2032,8 @@ static void xs_abort_connection(struct sock_xprt *transport) | |||
| 2050 | any.sa_family = AF_UNSPEC; | 2032 | any.sa_family = AF_UNSPEC; |
| 2051 | result = kernel_connect(transport->sock, &any, sizeof(any), 0); | 2033 | result = kernel_connect(transport->sock, &any, sizeof(any), 0); |
| 2052 | if (!result) | 2034 | if (!result) |
| 2053 | xs_sock_mark_closed(&transport->xprt); | 2035 | xs_sock_reset_connection_flags(&transport->xprt); |
| 2054 | else | 2036 | dprintk("RPC: AF_UNSPEC connect return code %d\n", result); |
| 2055 | dprintk("RPC: AF_UNSPEC connect return code %d\n", | ||
| 2056 | result); | ||
| 2057 | } | 2037 | } |
| 2058 | 2038 | ||
| 2059 | static void xs_tcp_reuse_connection(struct sock_xprt *transport) | 2039 | static void xs_tcp_reuse_connection(struct sock_xprt *transport) |
| @@ -2098,7 +2078,6 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
| 2098 | sk->sk_data_ready = xs_tcp_data_ready; | 2078 | sk->sk_data_ready = xs_tcp_data_ready; |
| 2099 | sk->sk_state_change = xs_tcp_state_change; | 2079 | sk->sk_state_change = xs_tcp_state_change; |
| 2100 | sk->sk_write_space = xs_tcp_write_space; | 2080 | sk->sk_write_space = xs_tcp_write_space; |
| 2101 | sk->sk_error_report = xs_error_report; | ||
| 2102 | sk->sk_allocation = GFP_ATOMIC; | 2081 | sk->sk_allocation = GFP_ATOMIC; |
| 2103 | 2082 | ||
| 2104 | /* socket options */ | 2083 | /* socket options */ |
diff --git a/net/tipc/handler.c b/net/tipc/handler.c index 111ff8300ae5..b36f0fcd9bdf 100644 --- a/net/tipc/handler.c +++ b/net/tipc/handler.c | |||
| @@ -116,7 +116,6 @@ void tipc_handler_stop(void) | |||
| 116 | return; | 116 | return; |
| 117 | 117 | ||
| 118 | handler_enabled = 0; | 118 | handler_enabled = 0; |
| 119 | tasklet_disable(&tipc_tasklet); | ||
| 120 | tasklet_kill(&tipc_tasklet); | 119 | tasklet_kill(&tipc_tasklet); |
| 121 | 120 | ||
| 122 | spin_lock_bh(&qitem_lock); | 121 | spin_lock_bh(&qitem_lock); |
