Commit 8d9ea7172edd2e52da26b9485b4c97969a0d2648
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: "A pile of fixes in response to yesterday's big merge. The SCTP HMAC thing hasn't been addressed yet, I'll take care of that myself if Neil and Vlad don't show signs of life by tomorrow. 1) Use after free of SKB in tuntap code. Fix by Eric Dumazet, reported by Dave Jones. 2) NFC LLCP code emits annoying kernel log message, triggerable by the user. From Dave Jones. 3) Fix several endianness bugs noticed by sparse in the bridging code, from Stephen Hemminger. 4) Ipv6 NDISC code doesn't take padding into account properly, fix from YOSHIFUJI Hideaki. 5) Add missing docs to ethtool_flow_ext struct, from Yan Burman." * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: bridge: fix icmpv6 endian bug and other sparse warnings net: ethool: Document struct ethtool_flow_ext ndisc: Fix padding error in link-layer address option. tuntap: dont use skb after netif_rx_ni(skb) nfc: remove noisy message from llcp_sock_sendmsg
Showing 5 changed files Side-by-side Diff
drivers/net/tun.c
... | ... | @@ -297,13 +297,12 @@ |
297 | 297 | spin_unlock_bh(&tun->lock); |
298 | 298 | } |
299 | 299 | |
300 | -static void tun_flow_update(struct tun_struct *tun, struct sk_buff *skb, | |
300 | +static void tun_flow_update(struct tun_struct *tun, u32 rxhash, | |
301 | 301 | u16 queue_index) |
302 | 302 | { |
303 | 303 | struct hlist_head *head; |
304 | 304 | struct tun_flow_entry *e; |
305 | 305 | unsigned long delay = tun->ageing_time; |
306 | - u32 rxhash = skb_get_rxhash(skb); | |
307 | 306 | |
308 | 307 | if (!rxhash) |
309 | 308 | return; |
... | ... | @@ -1010,6 +1009,7 @@ |
1010 | 1009 | int copylen; |
1011 | 1010 | bool zerocopy = false; |
1012 | 1011 | int err; |
1012 | + u32 rxhash; | |
1013 | 1013 | |
1014 | 1014 | if (!(tun->flags & TUN_NO_PI)) { |
1015 | 1015 | if ((len -= sizeof(pi)) > total_len) |
1016 | 1016 | |
... | ... | @@ -1162,12 +1162,13 @@ |
1162 | 1162 | skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; |
1163 | 1163 | } |
1164 | 1164 | |
1165 | + rxhash = skb_get_rxhash(skb); | |
1165 | 1166 | netif_rx_ni(skb); |
1166 | 1167 | |
1167 | 1168 | tun->dev->stats.rx_packets++; |
1168 | 1169 | tun->dev->stats.rx_bytes += len; |
1169 | 1170 | |
1170 | - tun_flow_update(tun, skb, tfile->queue_index); | |
1171 | + tun_flow_update(tun, rxhash, tfile->queue_index); | |
1171 | 1172 | return total_len; |
1172 | 1173 | } |
1173 | 1174 |
include/uapi/linux/ethtool.h
... | ... | @@ -503,9 +503,20 @@ |
503 | 503 | __u8 hdata[52]; |
504 | 504 | }; |
505 | 505 | |
506 | +/** | |
507 | + * struct ethtool_flow_ext - additional RX flow fields | |
508 | + * @h_dest: destination MAC address | |
509 | + * @vlan_etype: VLAN EtherType | |
510 | + * @vlan_tci: VLAN tag control information | |
511 | + * @data: user defined data | |
512 | + * | |
513 | + * Note, @vlan_etype, @vlan_tci, and @data are only valid if %FLOW_EXT | |
514 | + * is set in &struct ethtool_rx_flow_spec @flow_type. | |
515 | + * @h_dest is valid if %FLOW_MAC_EXT is set. | |
516 | + */ | |
506 | 517 | struct ethtool_flow_ext { |
507 | 518 | __u8 padding[2]; |
508 | - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ | |
519 | + unsigned char h_dest[ETH_ALEN]; | |
509 | 520 | __be16 vlan_etype; |
510 | 521 | __be16 vlan_tci; |
511 | 522 | __be32 data[2]; |
... | ... | @@ -519,7 +530,8 @@ |
519 | 530 | * @m_u: Masks for flow field bits to be matched |
520 | 531 | * @m_ext: Masks for additional field bits to be matched |
521 | 532 | * Note, all additional fields must be ignored unless @flow_type |
522 | - * includes the %FLOW_EXT flag. | |
533 | + * includes the %FLOW_EXT or %FLOW_MAC_EXT flag | |
534 | + * (see &struct ethtool_flow_ext description). | |
523 | 535 | * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC |
524 | 536 | * if packets should be discarded |
525 | 537 | * @location: Location of rule in the table. Locations must be |
net/bridge/br_multicast.c
... | ... | @@ -622,7 +622,7 @@ |
622 | 622 | struct net_bridge_port_group *br_multicast_new_port_group( |
623 | 623 | struct net_bridge_port *port, |
624 | 624 | struct br_ip *group, |
625 | - struct net_bridge_port_group *next) | |
625 | + struct net_bridge_port_group __rcu *next) | |
626 | 626 | { |
627 | 627 | struct net_bridge_port_group *p; |
628 | 628 | |
... | ... | @@ -632,7 +632,7 @@ |
632 | 632 | |
633 | 633 | p->addr = *group; |
634 | 634 | p->port = port; |
635 | - p->next = next; | |
635 | + rcu_assign_pointer(p->next, next); | |
636 | 636 | hlist_add_head(&p->mglist, &port->mglist); |
637 | 637 | setup_timer(&p->timer, br_multicast_port_group_expired, |
638 | 638 | (unsigned long)p); |
... | ... | @@ -1138,7 +1138,7 @@ |
1138 | 1138 | struct sk_buff *skb) |
1139 | 1139 | { |
1140 | 1140 | const struct ipv6hdr *ip6h = ipv6_hdr(skb); |
1141 | - struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb); | |
1141 | + struct mld_msg *mld; | |
1142 | 1142 | struct net_bridge_mdb_entry *mp; |
1143 | 1143 | struct mld2_query *mld2q; |
1144 | 1144 | struct net_bridge_port_group *p; |
... | ... | @@ -1165,6 +1165,7 @@ |
1165 | 1165 | if (max_delay) |
1166 | 1166 | group = &mld->mld_mca; |
1167 | 1167 | } else if (skb->len >= sizeof(*mld2q)) { |
1168 | + u16 mrc; | |
1168 | 1169 | if (!pskb_may_pull(skb, sizeof(*mld2q))) { |
1169 | 1170 | err = -EINVAL; |
1170 | 1171 | goto out; |
... | ... | @@ -1172,7 +1173,8 @@ |
1172 | 1173 | mld2q = (struct mld2_query *)icmp6_hdr(skb); |
1173 | 1174 | if (!mld2q->mld2q_nsrcs) |
1174 | 1175 | group = &mld2q->mld2q_mca; |
1175 | - max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(mld2q->mld2q_mrc) : 1; | |
1176 | + mrc = ntohs(mld2q->mld2q_mrc); | |
1177 | + max_delay = mrc ? MLDV2_MRC(mrc) : 1; | |
1176 | 1178 | } |
1177 | 1179 | |
1178 | 1180 | if (!group) |
net/ipv6/ndisc.c
... | ... | @@ -151,8 +151,8 @@ |
151 | 151 | static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len, |
152 | 152 | unsigned short addr_type) |
153 | 153 | { |
154 | - int space = NDISC_OPT_SPACE(data_len); | |
155 | 154 | int pad = ndisc_addr_option_pad(addr_type); |
155 | + int space = NDISC_OPT_SPACE(data_len + pad); | |
156 | 156 | |
157 | 157 | opt[0] = type; |
158 | 158 | opt[1] = space>>3; |