Commit 8d9ea717 authored by Linus Torvalds's avatar Linus Torvalds

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
parents f6e858a0 eca2a43b
......@@ -297,13 +297,12 @@ static void tun_flow_cleanup(unsigned long data)
spin_unlock_bh(&tun->lock);
}
static void tun_flow_update(struct tun_struct *tun, struct sk_buff *skb,
static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
u16 queue_index)
{
struct hlist_head *head;
struct tun_flow_entry *e;
unsigned long delay = tun->ageing_time;
u32 rxhash = skb_get_rxhash(skb);
if (!rxhash)
return;
......@@ -1010,6 +1009,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
int copylen;
bool zerocopy = false;
int err;
u32 rxhash;
if (!(tun->flags & TUN_NO_PI)) {
if ((len -= sizeof(pi)) > total_len)
......@@ -1162,12 +1162,13 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
}
rxhash = skb_get_rxhash(skb);
netif_rx_ni(skb);
tun->dev->stats.rx_packets++;
tun->dev->stats.rx_bytes += len;
tun_flow_update(tun, skb, tfile->queue_index);
tun_flow_update(tun, rxhash, tfile->queue_index);
return total_len;
}
......
......@@ -503,9 +503,20 @@ union ethtool_flow_union {
__u8 hdata[52];
};
/**
* struct ethtool_flow_ext - additional RX flow fields
* @h_dest: destination MAC address
* @vlan_etype: VLAN EtherType
* @vlan_tci: VLAN tag control information
* @data: user defined data
*
* Note, @vlan_etype, @vlan_tci, and @data are only valid if %FLOW_EXT
* is set in &struct ethtool_rx_flow_spec @flow_type.
* @h_dest is valid if %FLOW_MAC_EXT is set.
*/
struct ethtool_flow_ext {
__u8 padding[2];
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_dest[ETH_ALEN];
__be16 vlan_etype;
__be16 vlan_tci;
__be32 data[2];
......@@ -519,7 +530,8 @@ struct ethtool_flow_ext {
* @m_u: Masks for flow field bits to be matched
* @m_ext: Masks for additional field bits to be matched
* Note, all additional fields must be ignored unless @flow_type
* includes the %FLOW_EXT flag.
* includes the %FLOW_EXT or %FLOW_MAC_EXT flag
* (see &struct ethtool_flow_ext description).
* @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC
* if packets should be discarded
* @location: Location of rule in the table. Locations must be
......
......@@ -622,7 +622,7 @@ struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br,
struct net_bridge_port_group *br_multicast_new_port_group(
struct net_bridge_port *port,
struct br_ip *group,
struct net_bridge_port_group *next)
struct net_bridge_port_group __rcu *next)
{
struct net_bridge_port_group *p;
......@@ -632,7 +632,7 @@ struct net_bridge_port_group *br_multicast_new_port_group(
p->addr = *group;
p->port = port;
p->next = next;
rcu_assign_pointer(p->next, next);
hlist_add_head(&p->mglist, &port->mglist);
setup_timer(&p->timer, br_multicast_port_group_expired,
(unsigned long)p);
......@@ -1138,7 +1138,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
struct sk_buff *skb)
{
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb);
struct mld_msg *mld;
struct net_bridge_mdb_entry *mp;
struct mld2_query *mld2q;
struct net_bridge_port_group *p;
......@@ -1165,6 +1165,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
if (max_delay)
group = &mld->mld_mca;
} else if (skb->len >= sizeof(*mld2q)) {
u16 mrc;
if (!pskb_may_pull(skb, sizeof(*mld2q))) {
err = -EINVAL;
goto out;
......@@ -1172,7 +1173,8 @@ static int br_ip6_multicast_query(struct net_bridge *br,
mld2q = (struct mld2_query *)icmp6_hdr(skb);
if (!mld2q->mld2q_nsrcs)
group = &mld2q->mld2q_mca;
max_delay = mld2q->mld2q_mrc ? MLDV2_MRC(mld2q->mld2q_mrc) : 1;
mrc = ntohs(mld2q->mld2q_mrc);
max_delay = mrc ? MLDV2_MRC(mrc) : 1;
}
if (!group)
......
......@@ -151,8 +151,8 @@ static inline int ndisc_opt_addr_space(struct net_device *dev)
static u8 *ndisc_fill_addr_option(u8 *opt, int type, void *data, int data_len,
unsigned short addr_type)
{
int space = NDISC_OPT_SPACE(data_len);
int pad = ndisc_addr_option_pad(addr_type);
int space = NDISC_OPT_SPACE(data_len + pad);
opt[0] = type;
opt[1] = space>>3;
......
......@@ -614,10 +614,6 @@ static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (msg->msg_namelen < sizeof(*addr)) {
release_sock(sk);
pr_err("Invalid socket address length %d\n",
msg->msg_namelen);
return -EINVAL;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment