提交 11fe8839 编写于 作者: D David S. Miller

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

Conflicts:
	drivers/vhost/net.c
	net/bridge/br_device.c

Fix merge conflict in drivers/vhost/net.c with guidance from
Stephen Rothwell.

Revert the effects of net-2.6 commit 573201f3
since net-next-2.6 has fixes that make bridge netpoll work properly thus
we don't need it disabled.
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -677,7 +677,7 @@ static int ibmveth_close(struct net_device *netdev) ...@@ -677,7 +677,7 @@ static int ibmveth_close(struct net_device *netdev)
if (!adapter->pool_config) if (!adapter->pool_config)
netif_stop_queue(netdev); netif_stop_queue(netdev);
free_irq(netdev->irq, netdev); h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE);
do { do {
lpar_rc = h_free_logical_lan(adapter->vdev->unit_address); lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
...@@ -689,6 +689,8 @@ static int ibmveth_close(struct net_device *netdev) ...@@ -689,6 +689,8 @@ static int ibmveth_close(struct net_device *netdev)
lpar_rc); lpar_rc);
} }
free_irq(netdev->irq, netdev);
adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
ibmveth_cleanup(adapter); ibmveth_cleanup(adapter);
......
...@@ -1168,6 +1168,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) ...@@ -1168,6 +1168,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
int interrupts, nr_serviced = 0, i; int interrupts, nr_serviced = 0, i;
struct ei_device *ei_local; struct ei_device *ei_local;
int handled = 0; int handled = 0;
unsigned long flags;
e8390_base = dev->base_addr; e8390_base = dev->base_addr;
ei_local = netdev_priv(dev); ei_local = netdev_priv(dev);
...@@ -1176,7 +1177,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) ...@@ -1176,7 +1177,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
* Protect the irq test too. * Protect the irq test too.
*/ */
spin_lock(&ei_local->page_lock); spin_lock_irqsave(&ei_local->page_lock, flags);
if (ei_local->irqlock) if (ei_local->irqlock)
{ {
...@@ -1188,7 +1189,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) ...@@ -1188,7 +1189,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
dev->name, inb_p(e8390_base + EN0_ISR), dev->name, inb_p(e8390_base + EN0_ISR),
inb_p(e8390_base + EN0_IMR)); inb_p(e8390_base + EN0_IMR));
#endif #endif
spin_unlock(&ei_local->page_lock); spin_unlock_irqrestore(&ei_local->page_lock, flags);
return IRQ_NONE; return IRQ_NONE;
} }
...@@ -1261,7 +1262,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) ...@@ -1261,7 +1262,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
ei_local->irqlock = 0; ei_local->irqlock = 0;
outb_p(ENISR_ALL, e8390_base + EN0_IMR); outb_p(ENISR_ALL, e8390_base + EN0_IMR);
spin_unlock(&ei_local->page_lock); spin_unlock_irqrestore(&ei_local->page_lock, flags);
return IRQ_RETVAL(handled); return IRQ_RETVAL(handled);
} }
......
...@@ -1316,7 +1316,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, ...@@ -1316,7 +1316,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
{ 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 }, { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 },
/* 8168C family. */ /* 8168C family. */
{ 0x7cf00000, 0x3ca00000, RTL_GIGA_MAC_VER_24 }, { 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 },
{ 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 }, { 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 },
{ 0x7cf00000, 0x3c800000, RTL_GIGA_MAC_VER_18 }, { 0x7cf00000, 0x3c800000, RTL_GIGA_MAC_VER_18 },
{ 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_24 }, { 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_24 },
......
...@@ -330,6 +330,7 @@ static int prism2_pci_probe(struct pci_dev *pdev, ...@@ -330,6 +330,7 @@ static int prism2_pci_probe(struct pci_dev *pdev,
dev->irq = pdev->irq; dev->irq = pdev->irq;
hw_priv->mem_start = mem; hw_priv->mem_start = mem;
dev->base_addr = (unsigned long) mem;
prism2_pci_cor_sreset(local); prism2_pci_cor_sreset(local);
......
...@@ -958,6 +958,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) ...@@ -958,6 +958,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_MESH_POINT) |
BIT(NL80211_IFTYPE_WDS); BIT(NL80211_IFTYPE_WDS);
/*
* Initialize configuration work.
*/
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
/* /*
* Let the driver probe the device to detect the capabilities. * Let the driver probe the device to detect the capabilities.
*/ */
...@@ -967,11 +972,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) ...@@ -967,11 +972,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
goto exit; goto exit;
} }
/*
* Initialize configuration work.
*/
INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
/* /*
* Allocate queue array. * Allocate queue array.
*/ */
......
...@@ -177,8 +177,8 @@ static void handle_tx(struct vhost_net *net) ...@@ -177,8 +177,8 @@ static void handle_tx(struct vhost_net *net)
break; break;
} }
if (err != len) if (err != len)
pr_err("Truncated TX packet: " pr_debug("Truncated TX packet: "
" len %d != %zd\n", err, len); " len %d != %zd\n", err, len);
vhost_add_used_and_signal(&net->dev, vq, head, 0); vhost_add_used_and_signal(&net->dev, vq, head, 0);
total_len += len; total_len += len;
if (unlikely(total_len >= VHOST_NET_WEIGHT)) { if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
...@@ -275,8 +275,8 @@ static void handle_rx(struct vhost_net *net) ...@@ -275,8 +275,8 @@ static void handle_rx(struct vhost_net *net)
} }
/* TODO: Should check and handle checksum. */ /* TODO: Should check and handle checksum. */
if (err > len) { if (err > len) {
pr_err("Discarded truncated rx packet: " pr_debug("Discarded truncated rx packet: "
" len %d > %zd\n", err, len); " len %d > %zd\n", err, len);
vhost_discard_vq_desc(vq); vhost_discard_vq_desc(vq);
continue; continue;
} }
...@@ -527,17 +527,23 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) ...@@ -527,17 +527,23 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
/* start polling new socket */ /* start polling new socket */
oldsock = vq->private_data; oldsock = vq->private_data;
if (sock != oldsock){ if (sock != oldsock) {
vhost_net_disable_vq(n, vq); vhost_net_disable_vq(n, vq);
rcu_assign_pointer(vq->private_data, sock); rcu_assign_pointer(vq->private_data, sock);
vhost_net_enable_vq(n, vq); vhost_net_enable_vq(n, vq);
} }
done:
mutex_unlock(&vq->mutex);
if (oldsock) { if (oldsock) {
vhost_net_flush_vq(n, index); vhost_net_flush_vq(n, index);
fput(oldsock->file); fput(oldsock->file);
} }
mutex_unlock(&n->dev.mutex);
return 0;
err_vq: err_vq:
mutex_unlock(&vq->mutex); mutex_unlock(&vq->mutex);
err: err:
......
...@@ -1226,12 +1226,7 @@ static inline void sk_tx_queue_clear(struct sock *sk) ...@@ -1226,12 +1226,7 @@ static inline void sk_tx_queue_clear(struct sock *sk)
static inline int sk_tx_queue_get(const struct sock *sk) static inline int sk_tx_queue_get(const struct sock *sk)
{ {
return sk->sk_tx_queue_mapping; return sk ? sk->sk_tx_queue_mapping : -1;
}
static inline bool sk_tx_queue_recorded(const struct sock *sk)
{
return (sk && sk->sk_tx_queue_mapping >= 0);
} }
static inline void sk_set_socket(struct sock *sk, struct socket *sock) static inline void sk_set_socket(struct sock *sk, struct socket *sock)
......
...@@ -358,6 +358,11 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 ...@@ -358,6 +358,11 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
acl->sec_level = sec_level; acl->sec_level = sec_level;
acl->auth_type = auth_type; acl->auth_type = auth_type;
hci_acl_connect(acl); hci_acl_connect(acl);
} else {
if (acl->sec_level < sec_level)
acl->sec_level = sec_level;
if (acl->auth_type < auth_type)
acl->auth_type = auth_type;
} }
if (type == ACL_LINK) if (type == ACL_LINK)
......
...@@ -1049,6 +1049,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s ...@@ -1049,6 +1049,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (conn) { if (conn) {
if (!ev->status) if (!ev->status)
conn->link_mode |= HCI_LM_AUTH; conn->link_mode |= HCI_LM_AUTH;
else
conn->sec_level = BT_SECURITY_LOW;
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
......
...@@ -401,6 +401,11 @@ static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) ...@@ -401,6 +401,11 @@ static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
l2cap_send_sframe(pi, control); l2cap_send_sframe(pi, control);
} }
static inline int __l2cap_no_conn_pending(struct sock *sk)
{
return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
}
static void l2cap_do_start(struct sock *sk) static void l2cap_do_start(struct sock *sk)
{ {
struct l2cap_conn *conn = l2cap_pi(sk)->conn; struct l2cap_conn *conn = l2cap_pi(sk)->conn;
...@@ -409,12 +414,13 @@ static void l2cap_do_start(struct sock *sk) ...@@ -409,12 +414,13 @@ static void l2cap_do_start(struct sock *sk)
if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
return; return;
if (l2cap_check_security(sk)) { if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
struct l2cap_conn_req req; struct l2cap_conn_req req;
req.scid = cpu_to_le16(l2cap_pi(sk)->scid); req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm; req.psm = l2cap_pi(sk)->psm;
l2cap_pi(sk)->ident = l2cap_get_ident(conn); l2cap_pi(sk)->ident = l2cap_get_ident(conn);
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, l2cap_pi(sk)->ident, l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_REQ, sizeof(req), &req); L2CAP_CONN_REQ, sizeof(req), &req);
...@@ -464,12 +470,14 @@ static void l2cap_conn_start(struct l2cap_conn *conn) ...@@ -464,12 +470,14 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
} }
if (sk->sk_state == BT_CONNECT) { if (sk->sk_state == BT_CONNECT) {
if (l2cap_check_security(sk)) { if (l2cap_check_security(sk) &&
__l2cap_no_conn_pending(sk)) {
struct l2cap_conn_req req; struct l2cap_conn_req req;
req.scid = cpu_to_le16(l2cap_pi(sk)->scid); req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm; req.psm = l2cap_pi(sk)->psm;
l2cap_pi(sk)->ident = l2cap_get_ident(conn); l2cap_pi(sk)->ident = l2cap_get_ident(conn);
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, l2cap_pi(sk)->ident, l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_REQ, sizeof(req), &req); L2CAP_CONN_REQ, sizeof(req), &req);
...@@ -2912,7 +2920,6 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd ...@@ -2912,7 +2920,6 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
l2cap_pi(sk)->ident = 0; l2cap_pi(sk)->ident = 0;
l2cap_pi(sk)->dcid = dcid; l2cap_pi(sk)->dcid = dcid;
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND; l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
...@@ -4404,6 +4411,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) ...@@ -4404,6 +4411,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
req.psm = l2cap_pi(sk)->psm; req.psm = l2cap_pi(sk)->psm;
l2cap_pi(sk)->ident = l2cap_get_ident(conn); l2cap_pi(sk)->ident = l2cap_get_ident(conn);
l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, l2cap_pi(sk)->ident, l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_REQ, sizeof(req), &req); L2CAP_CONN_REQ, sizeof(req), &req);
......
...@@ -1910,8 +1910,16 @@ static int dev_gso_segment(struct sk_buff *skb) ...@@ -1910,8 +1910,16 @@ static int dev_gso_segment(struct sk_buff *skb)
*/ */
static inline void skb_orphan_try(struct sk_buff *skb) static inline void skb_orphan_try(struct sk_buff *skb)
{ {
if (!skb_tx(skb)->flags) struct sock *sk = skb->sk;
if (sk && !skb_tx(skb)->flags) {
/* skb_tx_hash() wont be able to get sk.
* We copy sk_hash into skb->rxhash
*/
if (!skb->rxhash)
skb->rxhash = sk->sk_hash;
skb_orphan(skb); skb_orphan(skb);
}
} }
/* /*
...@@ -2029,8 +2037,7 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb) ...@@ -2029,8 +2037,7 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
if (skb->sk && skb->sk->sk_hash) if (skb->sk && skb->sk->sk_hash)
hash = skb->sk->sk_hash; hash = skb->sk->sk_hash;
else else
hash = (__force u16) skb->protocol; hash = (__force u16) skb->protocol ^ skb->rxhash;
hash = jhash_1word(hash, hashrnd); hash = jhash_1word(hash, hashrnd);
return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32); return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
...@@ -2053,12 +2060,11 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index) ...@@ -2053,12 +2060,11 @@ static inline u16 dev_cap_txqueue(struct net_device *dev, u16 queue_index)
static struct netdev_queue *dev_pick_tx(struct net_device *dev, static struct netdev_queue *dev_pick_tx(struct net_device *dev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
u16 queue_index; int queue_index;
struct sock *sk = skb->sk; struct sock *sk = skb->sk;
if (sk_tx_queue_recorded(sk)) { queue_index = sk_tx_queue_get(sk);
queue_index = sk_tx_queue_get(sk); if (queue_index < 0) {
} else {
const struct net_device_ops *ops = dev->netdev_ops; const struct net_device_ops *ops = dev->netdev_ops;
if (ops->ndo_select_queue) { if (ops->ndo_select_queue) {
......
...@@ -949,7 +949,10 @@ static void neigh_update_hhs(struct neighbour *neigh) ...@@ -949,7 +949,10 @@ static void neigh_update_hhs(struct neighbour *neigh)
{ {
struct hh_cache *hh; struct hh_cache *hh;
void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *) void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *)
= neigh->dev->header_ops->cache_update; = NULL;
if (neigh->dev->header_ops)
update = neigh->dev->header_ops->cache_update;
if (update) { if (update) {
for (hh = neigh->hh; hh; hh = hh->hh_next) { for (hh = neigh->hh; hh; hh = hh->hh_next) {
......
menuconfig NET_DSA menuconfig NET_DSA
bool "Distributed Switch Architecture support" bool "Distributed Switch Architecture support"
default n default n
depends on EXPERIMENTAL && !S390 depends on EXPERIMENTAL && NET_ETHERNET && !S390
select PHYLIB select PHYLIB
---help--- ---help---
This allows you to use hardware switch chips that use This allows you to use hardware switch chips that use
......
...@@ -442,8 +442,10 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -442,8 +442,10 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
int err; int err;
err = ipmr_fib_lookup(net, &fl, &mrt); err = ipmr_fib_lookup(net, &fl, &mrt);
if (err < 0) if (err < 0) {
kfree_skb(skb);
return err; return err;
}
read_lock(&mrt_lock); read_lock(&mrt_lock);
dev->stats.tx_bytes += skb->len; dev->stats.tx_bytes += skb->len;
...@@ -1728,8 +1730,10 @@ int ip_mr_input(struct sk_buff *skb) ...@@ -1728,8 +1730,10 @@ int ip_mr_input(struct sk_buff *skb)
goto dont_forward; goto dont_forward;
err = ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt); err = ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt);
if (err < 0) if (err < 0) {
kfree_skb(skb);
return err; return err;
}
if (!local) { if (!local) {
if (IPCB(skb)->opt.router_alert) { if (IPCB(skb)->opt.router_alert) {
......
...@@ -608,6 +608,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos, ...@@ -608,6 +608,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
ssize_t spliced; ssize_t spliced;
int ret; int ret;
sock_rps_record_flow(sk);
/* /*
* We can't seek on a socket input * We can't seek on a socket input
*/ */
......
...@@ -2210,6 +2210,9 @@ void tcp_xmit_retransmit_queue(struct sock *sk) ...@@ -2210,6 +2210,9 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
int mib_idx; int mib_idx;
int fwd_rexmitting = 0; int fwd_rexmitting = 0;
if (!tp->packets_out)
return;
if (!tp->lost_out) if (!tp->lost_out)
tp->retransmit_high = tp->snd_una; tp->retransmit_high = tp->snd_una;
......
...@@ -347,11 +347,12 @@ static const struct xfrm_type mip6_destopt_type = ...@@ -347,11 +347,12 @@ static const struct xfrm_type mip6_destopt_type =
static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb) static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
{ {
struct ipv6hdr *iph = ipv6_hdr(skb);
struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data; struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data;
int err = rt2->rt_hdr.nexthdr; int err = rt2->rt_hdr.nexthdr;
spin_lock(&x->lock); spin_lock(&x->lock);
if (!ipv6_addr_equal(&rt2->addr, (struct in6_addr *)x->coaddr) && if (!ipv6_addr_equal(&iph->daddr, (struct in6_addr *)x->coaddr) &&
!ipv6_addr_any((struct in6_addr *)x->coaddr)) !ipv6_addr_any((struct in6_addr *)x->coaddr))
err = -ENOENT; err = -ENOENT;
spin_unlock(&x->lock); spin_unlock(&x->lock);
......
...@@ -698,6 +698,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp) ...@@ -698,6 +698,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)
newsk = NULL; newsk = NULL;
goto out; goto out;
} }
kfree_skb(oskb);
sock_hold(sk); sock_hold(sk);
pep_sk(newsk)->listener = sk; pep_sk(newsk)->listener = sk;
......
...@@ -205,7 +205,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, ...@@ -205,7 +205,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
{ {
struct icmphdr *icmph; struct icmphdr *icmph;
if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph))) if (!pskb_may_pull(skb, ihl + sizeof(*icmph)))
goto drop; goto drop;
icmph = (void *)(skb_network_header(skb) + ihl); icmph = (void *)(skb_network_header(skb) + ihl);
...@@ -215,6 +215,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, ...@@ -215,6 +215,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
(icmph->type != ICMP_PARAMETERPROB)) (icmph->type != ICMP_PARAMETERPROB))
break; break;
if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph)))
goto drop;
iph = (void *)(icmph + 1); iph = (void *)(icmph + 1);
if (egress) if (egress)
addr = iph->daddr; addr = iph->daddr;
......
...@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, ...@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
/* Try to instantiate a bundle */ /* Try to instantiate a bundle */
err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family); err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
if (err < 0) { if (err <= 0) {
if (err != -EAGAIN) if (err != 0 && err != -EAGAIN)
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR); XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
return ERR_PTR(err); return ERR_PTR(err);
} }
...@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir, ...@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir,
goto make_dummy_bundle; goto make_dummy_bundle;
dst_hold(&xdst->u.dst); dst_hold(&xdst->u.dst);
return oldflo; return oldflo;
} else if (new_xdst == NULL) {
num_xfrms = 0;
if (oldflo == NULL)
goto make_dummy_bundle;
xdst->num_xfrms = 0;
dst_hold(&xdst->u.dst);
return oldflo;
} }
/* Kill the previous bundle */ /* Kill the previous bundle */
...@@ -1760,6 +1767,10 @@ int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, struct flowi *fl, ...@@ -1760,6 +1767,10 @@ int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, struct flowi *fl,
xfrm_pols_put(pols, num_pols); xfrm_pols_put(pols, num_pols);
err = PTR_ERR(xdst); err = PTR_ERR(xdst);
goto dropdst; goto dropdst;
} else if (xdst == NULL) {
num_xfrms = 0;
drop_pols = num_pols;
goto no_transform;
} }
spin_lock_bh(&xfrm_policy_sk_bundle_lock); spin_lock_bh(&xfrm_policy_sk_bundle_lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册