diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/bnep/netdev.c | 2 | ||||
-rw-r--r-- | net/bridge/br_multicast.c | 21 | ||||
-rw-r--r-- | net/bridge/br_netfilter.c | 3 | ||||
-rw-r--r-- | net/core/dev.c | 18 | ||||
-rw-r--r-- | net/core/ethtool.c | 41 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 2 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 6 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 3 |
10 files changed, 76 insertions, 24 deletions
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index 0faad5ce6dc4..8c100c9dae28 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c | |||
@@ -104,6 +104,8 @@ static void bnep_net_set_mc_list(struct net_device *dev) | |||
104 | break; | 104 | break; |
105 | memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN); | 105 | memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN); |
106 | memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN); | 106 | memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN); |
107 | |||
108 | i++; | ||
107 | } | 109 | } |
108 | r->len = htons(skb->len - len); | 110 | r->len = htons(skb->len - len); |
109 | } | 111 | } |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 9d21d98ae5fa..27ae946363f1 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -99,6 +99,15 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get( | |||
99 | return NULL; | 99 | return NULL; |
100 | } | 100 | } |
101 | 101 | ||
102 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | ||
103 | struct net_bridge_mdb_htable *mdb, struct br_ip *dst) | ||
104 | { | ||
105 | if (!mdb) | ||
106 | return NULL; | ||
107 | |||
108 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); | ||
109 | } | ||
110 | |||
102 | static struct net_bridge_mdb_entry *br_mdb_ip4_get( | 111 | static struct net_bridge_mdb_entry *br_mdb_ip4_get( |
103 | struct net_bridge_mdb_htable *mdb, __be32 dst) | 112 | struct net_bridge_mdb_htable *mdb, __be32 dst) |
104 | { | 113 | { |
@@ -107,7 +116,7 @@ static struct net_bridge_mdb_entry *br_mdb_ip4_get( | |||
107 | br_dst.u.ip4 = dst; | 116 | br_dst.u.ip4 = dst; |
108 | br_dst.proto = htons(ETH_P_IP); | 117 | br_dst.proto = htons(ETH_P_IP); |
109 | 118 | ||
110 | return __br_mdb_ip_get(mdb, &br_dst, __br_ip4_hash(mdb, dst)); | 119 | return br_mdb_ip_get(mdb, &br_dst); |
111 | } | 120 | } |
112 | 121 | ||
113 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 122 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
@@ -119,23 +128,17 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get( | |||
119 | ipv6_addr_copy(&br_dst.u.ip6, dst); | 128 | ipv6_addr_copy(&br_dst.u.ip6, dst); |
120 | br_dst.proto = htons(ETH_P_IPV6); | 129 | br_dst.proto = htons(ETH_P_IPV6); |
121 | 130 | ||
122 | return __br_mdb_ip_get(mdb, &br_dst, __br_ip6_hash(mdb, dst)); | 131 | return br_mdb_ip_get(mdb, &br_dst); |
123 | } | 132 | } |
124 | #endif | 133 | #endif |
125 | 134 | ||
126 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | ||
127 | struct net_bridge_mdb_htable *mdb, struct br_ip *dst) | ||
128 | { | ||
129 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); | ||
130 | } | ||
131 | |||
132 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, | 135 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, |
133 | struct sk_buff *skb) | 136 | struct sk_buff *skb) |
134 | { | 137 | { |
135 | struct net_bridge_mdb_htable *mdb = br->mdb; | 138 | struct net_bridge_mdb_htable *mdb = br->mdb; |
136 | struct br_ip ip; | 139 | struct br_ip ip; |
137 | 140 | ||
138 | if (!mdb || br->multicast_disabled) | 141 | if (br->multicast_disabled) |
139 | return NULL; | 142 | return NULL; |
140 | 143 | ||
141 | if (BR_INPUT_SKB_CB(skb)->igmp) | 144 | if (BR_INPUT_SKB_CB(skb)->igmp) |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 9fdf1b116bd7..2c911c0759c2 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
@@ -598,6 +598,9 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, | |||
598 | 598 | ||
599 | pskb_trim_rcsum(skb, len); | 599 | pskb_trim_rcsum(skb, len); |
600 | 600 | ||
601 | /* BUG: Should really parse the IP options here. */ | ||
602 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | ||
603 | |||
601 | nf_bridge_put(skb->nf_bridge); | 604 | nf_bridge_put(skb->nf_bridge); |
602 | if (!nf_bridge_alloc(skb)) | 605 | if (!nf_bridge_alloc(skb)) |
603 | return NF_DROP; | 606 | return NF_DROP; |
diff --git a/net/core/dev.c b/net/core/dev.c index 92482d7a87a9..eb4201cf9c8c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1550,6 +1550,24 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) | |||
1550 | rcu_read_unlock(); | 1550 | rcu_read_unlock(); |
1551 | } | 1551 | } |
1552 | 1552 | ||
1553 | /* | ||
1554 | * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues | ||
1555 | * greater then real_num_tx_queues stale skbs on the qdisc must be flushed. | ||
1556 | */ | ||
1557 | void netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) | ||
1558 | { | ||
1559 | unsigned int real_num = dev->real_num_tx_queues; | ||
1560 | |||
1561 | if (unlikely(txq > dev->num_tx_queues)) | ||
1562 | ; | ||
1563 | else if (txq > real_num) | ||
1564 | dev->real_num_tx_queues = txq; | ||
1565 | else if (txq < real_num) { | ||
1566 | dev->real_num_tx_queues = txq; | ||
1567 | qdisc_reset_all_tx_gt(dev, txq); | ||
1568 | } | ||
1569 | } | ||
1570 | EXPORT_SYMBOL(netif_set_real_num_tx_queues); | ||
1553 | 1571 | ||
1554 | static inline void __netif_reschedule(struct Qdisc *q) | 1572 | static inline void __netif_reschedule(struct Qdisc *q) |
1555 | { | 1573 | { |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 072d1d3796cb..7a85367b3c2f 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -300,23 +300,33 @@ out: | |||
300 | } | 300 | } |
301 | 301 | ||
302 | static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, | 302 | static noinline_for_stack int ethtool_set_rxnfc(struct net_device *dev, |
303 | void __user *useraddr) | 303 | u32 cmd, void __user *useraddr) |
304 | { | 304 | { |
305 | struct ethtool_rxnfc cmd; | 305 | struct ethtool_rxnfc info; |
306 | size_t info_size = sizeof(info); | ||
306 | 307 | ||
307 | if (!dev->ethtool_ops->set_rxnfc) | 308 | if (!dev->ethtool_ops->set_rxnfc) |
308 | return -EOPNOTSUPP; | 309 | return -EOPNOTSUPP; |
309 | 310 | ||
310 | if (copy_from_user(&cmd, useraddr, sizeof(cmd))) | 311 | /* struct ethtool_rxnfc was originally defined for |
312 | * ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data | ||
313 | * members. User-space might still be using that | ||
314 | * definition. */ | ||
315 | if (cmd == ETHTOOL_SRXFH) | ||
316 | info_size = (offsetof(struct ethtool_rxnfc, data) + | ||
317 | sizeof(info.data)); | ||
318 | |||
319 | if (copy_from_user(&info, useraddr, info_size)) | ||
311 | return -EFAULT; | 320 | return -EFAULT; |
312 | 321 | ||
313 | return dev->ethtool_ops->set_rxnfc(dev, &cmd); | 322 | return dev->ethtool_ops->set_rxnfc(dev, &info); |
314 | } | 323 | } |
315 | 324 | ||
316 | static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, | 325 | static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, |
317 | void __user *useraddr) | 326 | u32 cmd, void __user *useraddr) |
318 | { | 327 | { |
319 | struct ethtool_rxnfc info; | 328 | struct ethtool_rxnfc info; |
329 | size_t info_size = sizeof(info); | ||
320 | const struct ethtool_ops *ops = dev->ethtool_ops; | 330 | const struct ethtool_ops *ops = dev->ethtool_ops; |
321 | int ret; | 331 | int ret; |
322 | void *rule_buf = NULL; | 332 | void *rule_buf = NULL; |
@@ -324,13 +334,22 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, | |||
324 | if (!ops->get_rxnfc) | 334 | if (!ops->get_rxnfc) |
325 | return -EOPNOTSUPP; | 335 | return -EOPNOTSUPP; |
326 | 336 | ||
327 | if (copy_from_user(&info, useraddr, sizeof(info))) | 337 | /* struct ethtool_rxnfc was originally defined for |
338 | * ETHTOOL_{G,S}RXFH with only the cmd, flow_type and data | ||
339 | * members. User-space might still be using that | ||
340 | * definition. */ | ||
341 | if (cmd == ETHTOOL_GRXFH) | ||
342 | info_size = (offsetof(struct ethtool_rxnfc, data) + | ||
343 | sizeof(info.data)); | ||
344 | |||
345 | if (copy_from_user(&info, useraddr, info_size)) | ||
328 | return -EFAULT; | 346 | return -EFAULT; |
329 | 347 | ||
330 | if (info.cmd == ETHTOOL_GRXCLSRLALL) { | 348 | if (info.cmd == ETHTOOL_GRXCLSRLALL) { |
331 | if (info.rule_cnt > 0) { | 349 | if (info.rule_cnt > 0) { |
332 | rule_buf = kmalloc(info.rule_cnt * sizeof(u32), | 350 | if (info.rule_cnt <= KMALLOC_MAX_SIZE / sizeof(u32)) |
333 | GFP_USER); | 351 | rule_buf = kmalloc(info.rule_cnt * sizeof(u32), |
352 | GFP_USER); | ||
334 | if (!rule_buf) | 353 | if (!rule_buf) |
335 | return -ENOMEM; | 354 | return -ENOMEM; |
336 | } | 355 | } |
@@ -341,7 +360,7 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev, | |||
341 | goto err_out; | 360 | goto err_out; |
342 | 361 | ||
343 | ret = -EFAULT; | 362 | ret = -EFAULT; |
344 | if (copy_to_user(useraddr, &info, sizeof(info))) | 363 | if (copy_to_user(useraddr, &info, info_size)) |
345 | goto err_out; | 364 | goto err_out; |
346 | 365 | ||
347 | if (rule_buf) { | 366 | if (rule_buf) { |
@@ -1572,12 +1591,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
1572 | case ETHTOOL_GRXCLSRLCNT: | 1591 | case ETHTOOL_GRXCLSRLCNT: |
1573 | case ETHTOOL_GRXCLSRULE: | 1592 | case ETHTOOL_GRXCLSRULE: |
1574 | case ETHTOOL_GRXCLSRLALL: | 1593 | case ETHTOOL_GRXCLSRLALL: |
1575 | rc = ethtool_get_rxnfc(dev, useraddr); | 1594 | rc = ethtool_get_rxnfc(dev, ethcmd, useraddr); |
1576 | break; | 1595 | break; |
1577 | case ETHTOOL_SRXFH: | 1596 | case ETHTOOL_SRXFH: |
1578 | case ETHTOOL_SRXCLSRLDEL: | 1597 | case ETHTOOL_SRXCLSRLDEL: |
1579 | case ETHTOOL_SRXCLSRLINS: | 1598 | case ETHTOOL_SRXCLSRLINS: |
1580 | rc = ethtool_set_rxnfc(dev, useraddr); | 1599 | rc = ethtool_set_rxnfc(dev, ethcmd, useraddr); |
1581 | break; | 1600 | break; |
1582 | case ETHTOOL_GGRO: | 1601 | case ETHTOOL_GGRO: |
1583 | rc = ethtool_get_gro(dev, useraddr); | 1602 | rc = ethtool_get_gro(dev, useraddr); |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 349327092c9e..869078d4eeb9 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -108,6 +108,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
108 | u8 *xprth = skb_network_header(skb) + iph->ihl * 4; | 108 | u8 *xprth = skb_network_header(skb) + iph->ihl * 4; |
109 | 109 | ||
110 | memset(fl, 0, sizeof(struct flowi)); | 110 | memset(fl, 0, sizeof(struct flowi)); |
111 | fl->mark = skb->mark; | ||
112 | |||
111 | if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) { | 113 | if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) { |
112 | switch (iph->protocol) { | 114 | switch (iph->protocol) { |
113 | case IPPROTO_UDP: | 115 | case IPPROTO_UDP: |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 1fc46fc60efd..58841c4ae947 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -586,6 +586,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | |||
586 | src_addr = solicited_addr; | 586 | src_addr = solicited_addr; |
587 | if (ifp->flags & IFA_F_OPTIMISTIC) | 587 | if (ifp->flags & IFA_F_OPTIMISTIC) |
588 | override = 0; | 588 | override = 0; |
589 | inc_opt |= ifp->idev->cnf.force_tllao; | ||
589 | in6_ifa_put(ifp); | 590 | in6_ifa_put(ifp); |
590 | } else { | 591 | } else { |
591 | if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr, | 592 | if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr, |
@@ -599,7 +600,6 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | |||
599 | icmp6h.icmp6_solicited = solicited; | 600 | icmp6h.icmp6_solicited = solicited; |
600 | icmp6h.icmp6_override = override; | 601 | icmp6h.icmp6_override = override; |
601 | 602 | ||
602 | inc_opt |= ifp->idev->cnf.force_tllao; | ||
603 | __ndisc_send(dev, neigh, daddr, src_addr, | 603 | __ndisc_send(dev, neigh, daddr, src_addr, |
604 | &icmp6h, solicited_addr, | 604 | &icmp6h, solicited_addr, |
605 | inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); | 605 | inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 47d227713758..2933396e0281 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -97,9 +97,11 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) | |||
97 | fl.fl_ip_dport = otcph.source; | 97 | fl.fl_ip_dport = otcph.source; |
98 | security_skb_classify_flow(oldskb, &fl); | 98 | security_skb_classify_flow(oldskb, &fl); |
99 | dst = ip6_route_output(net, NULL, &fl); | 99 | dst = ip6_route_output(net, NULL, &fl); |
100 | if (dst == NULL) | 100 | if (dst == NULL || dst->error) { |
101 | dst_release(dst); | ||
101 | return; | 102 | return; |
102 | if (dst->error || xfrm_lookup(net, &dst, &fl, NULL, 0)) | 103 | } |
104 | if (xfrm_lookup(net, &dst, &fl, NULL, 0)) | ||
103 | return; | 105 | return; |
104 | 106 | ||
105 | hh_len = (dst->dev->hard_header_len + 15)&~15; | 107 | hh_len = (dst->dev->hard_header_len + 15)&~15; |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 4a0e77e14468..6baeabbbca82 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -124,6 +124,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
124 | u8 nexthdr = nh[IP6CB(skb)->nhoff]; | 124 | u8 nexthdr = nh[IP6CB(skb)->nhoff]; |
125 | 125 | ||
126 | memset(fl, 0, sizeof(struct flowi)); | 126 | memset(fl, 0, sizeof(struct flowi)); |
127 | fl->mark = skb->mark; | ||
128 | |||
127 | ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr); | 129 | ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr); |
128 | ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr); | 130 | ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr); |
129 | 131 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 593c06be6b62..037d956353e5 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -2300,7 +2300,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, | |||
2300 | return 0; | 2300 | return 0; |
2301 | if (xdst->xfrm_genid != dst->xfrm->genid) | 2301 | if (xdst->xfrm_genid != dst->xfrm->genid) |
2302 | return 0; | 2302 | return 0; |
2303 | if (xdst->policy_genid != atomic_read(&xdst->pols[0]->genid)) | 2303 | if (xdst->num_pols > 0 && |
2304 | xdst->policy_genid != atomic_read(&xdst->pols[0]->genid)) | ||
2304 | return 0; | 2305 | return 0; |
2305 | 2306 | ||
2306 | if (strict && fl && | 2307 | if (strict && fl && |