Skip to content

Commit

Permalink
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Browse files Browse the repository at this point in the history
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [IPV4/IPV6]: Setting 0 for unused port field in RAW IP recvmsg().
  [IPV4] ipmr: ip multicast route bug fix.
  [TG3]: Update version and reldate
  [TG3]: Handle tg3_init_rings() failures
  [TG3]: Add tg3_restart_hw()
  [IPV4]: Clear the whole IPCB, this clears also IPCB(skb)->flags.
  [IPV6]: Clean skb cb on IPv6 input.
  [NETFILTER]: Demote xt_sctp to EXPERIMENTAL
  [NETFILTER]: bridge netfilter: add deferred output hooks to feature-removal-schedule
  [NETFILTER]: xt_pkttype: fix mismatches on locally generated packets
  [NETFILTER]: SNMP NAT: fix byteorder confusion
  [NETFILTER]: conntrack: fix SYSCTL=n compile
  [NETFILTER]: nf_queue: handle NF_STOP and unknown verdicts in nf_reinject
  [NETFILTER]: H.323 helper: fix possible NULL-ptr dereference
  • Loading branch information
Linus Torvalds committed Jul 26, 2006
2 parents 153d7f3 + f59fc7f commit 761a126
Show file tree
Hide file tree
Showing 17 changed files with 167 additions and 51 deletions.
16 changes: 16 additions & 0 deletions Documentation/feature-removal-schedule.txt
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,19 @@ Why: These drivers never compiled since they were added to the kernel
Who: Jean Delvare <khali@linux-fr.org>

---------------------------

What: Bridge netfilter deferred IPv4/IPv6 output hook calling
When: January 2007
Why: The deferred output hooks are a layering violation causing unusual
and broken behaviour on bridge devices. Examples of things they
break include QoS classifation using the MARK or CLASSIFY targets,
the IPsec policy match and connection tracking with VLANs on a
bridge. Their only use is to enable bridge output port filtering
within iptables with the physdev match, which can also be done by
combining iptables and ebtables using netfilter marks. Until it
will get removed the hook deferral is disabled by default and is
only enabled when needed.

Who: Patrick McHardy <kaber@trash.net>

---------------------------
116 changes: 87 additions & 29 deletions drivers/net/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@

#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "3.62"
#define DRV_MODULE_RELDATE "June 30, 2006"
#define DRV_MODULE_VERSION "3.63"
#define DRV_MODULE_RELDATE "July 25, 2006"

#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
Expand Down Expand Up @@ -3590,6 +3590,28 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id,
static int tg3_init_hw(struct tg3 *, int);
static int tg3_halt(struct tg3 *, int, int);

/* Restart hardware after configuration changes, self-test, etc.
* Invoked with tp->lock held.
*/
static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
{
int err;

err = tg3_init_hw(tp, reset_phy);
if (err) {
printk(KERN_ERR PFX "%s: Failed to re-initialize device, "
"aborting.\n", tp->dev->name);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_full_unlock(tp);
del_timer_sync(&tp->timer);
tp->irq_sync = 0;
netif_poll_enable(tp->dev);
dev_close(tp->dev);
tg3_full_lock(tp, 0);
}
return err;
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void tg3_poll_controller(struct net_device *dev)
{
Expand Down Expand Up @@ -3630,13 +3652,15 @@ static void tg3_reset_task(void *_data)
}

tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
tg3_init_hw(tp, 1);
if (tg3_init_hw(tp, 1))
goto out;

tg3_netif_start(tp);

if (restart_timer)
mod_timer(&tp->timer, jiffies + 1);

out:
tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK;

tg3_full_unlock(tp);
Expand Down Expand Up @@ -4124,6 +4148,7 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
static int tg3_change_mtu(struct net_device *dev, int new_mtu)
{
struct tg3 *tp = netdev_priv(dev);
int err;

if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp))
return -EINVAL;
Expand All @@ -4144,13 +4169,14 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)

tg3_set_mtu(dev, tp, new_mtu);

tg3_init_hw(tp, 0);
err = tg3_restart_hw(tp, 0);

tg3_netif_start(tp);
if (!err)
tg3_netif_start(tp);

tg3_full_unlock(tp);

return 0;
return err;
}

/* Free up pending packets in all rx/tx rings.
Expand Down Expand Up @@ -4232,7 +4258,7 @@ static void tg3_free_rings(struct tg3 *tp)
* end up in the driver. tp->{tx,}lock are held and thus
* we may not sleep.
*/
static void tg3_init_rings(struct tg3 *tp)
static int tg3_init_rings(struct tg3 *tp)
{
u32 i;

Expand Down Expand Up @@ -4281,18 +4307,38 @@ static void tg3_init_rings(struct tg3 *tp)

/* Now allocate fresh SKBs for each rx ring. */
for (i = 0; i < tp->rx_pending; i++) {
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD,
-1, i) < 0)
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, -1, i) < 0) {
printk(KERN_WARNING PFX
"%s: Using a smaller RX standard ring, "
"only %d out of %d buffers were allocated "
"successfully.\n",
tp->dev->name, i, tp->rx_pending);
if (i == 0)
return -ENOMEM;
tp->rx_pending = i;
break;
}
}

if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
for (i = 0; i < tp->rx_jumbo_pending; i++) {
if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO,
-1, i) < 0)
-1, i) < 0) {
printk(KERN_WARNING PFX
"%s: Using a smaller RX jumbo ring, "
"only %d out of %d buffers were "
"allocated successfully.\n",
tp->dev->name, i, tp->rx_jumbo_pending);
if (i == 0) {
tg3_free_rings(tp);
return -ENOMEM;
}
tp->rx_jumbo_pending = i;
break;
}
}
}
return 0;
}

/*
Expand Down Expand Up @@ -5815,6 +5861,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
{
struct tg3 *tp = netdev_priv(dev);
struct sockaddr *addr = p;
int err = 0;

if (!is_valid_ether_addr(addr->sa_data))
return -EINVAL;
Expand All @@ -5832,17 +5879,17 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
tg3_full_lock(tp, 1);

tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_init_hw(tp, 0);

tg3_netif_start(tp);
err = tg3_restart_hw(tp, 0);
if (!err)
tg3_netif_start(tp);
tg3_full_unlock(tp);
} else {
spin_lock_bh(&tp->lock);
__tg3_set_mac_addr(tp);
spin_unlock_bh(&tp->lock);
}

return 0;
return err;
}

/* tp->lock is held. */
Expand Down Expand Up @@ -5942,7 +5989,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
* can only do this after the hardware has been
* successfully reset.
*/
tg3_init_rings(tp);
err = tg3_init_rings(tp);
if (err)
return err;

/* This value is determined during the probe time DMA
* engine test, tg3_test_dma.
Expand Down Expand Up @@ -7956,7 +8005,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
{
struct tg3 *tp = netdev_priv(dev);
int irq_sync = 0;
int irq_sync = 0, err = 0;

if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
(ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
Expand All @@ -7980,13 +8029,14 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e

if (netif_running(dev)) {
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_init_hw(tp, 1);
tg3_netif_start(tp);
err = tg3_restart_hw(tp, 1);
if (!err)
tg3_netif_start(tp);
}

tg3_full_unlock(tp);

return 0;
return err;
}

static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
Expand All @@ -8001,7 +8051,7 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
{
struct tg3 *tp = netdev_priv(dev);
int irq_sync = 0;
int irq_sync = 0, err = 0;

if (netif_running(dev)) {
tg3_netif_stop(tp);
Expand All @@ -8025,13 +8075,14 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam

if (netif_running(dev)) {
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
tg3_init_hw(tp, 1);
tg3_netif_start(tp);
err = tg3_restart_hw(tp, 1);
if (!err)
tg3_netif_start(tp);
}

tg3_full_unlock(tp);

return 0;
return err;
}

static u32 tg3_get_rx_csum(struct net_device *dev)
Expand Down Expand Up @@ -8666,7 +8717,9 @@ static int tg3_test_loopback(struct tg3 *tp)
if (!netif_running(tp->dev))
return TG3_LOOPBACK_FAILED;

tg3_reset_hw(tp, 1);
err = tg3_reset_hw(tp, 1);
if (err)
return TG3_LOOPBACK_FAILED;

if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
err |= TG3_MAC_LOOPBACK_FAILED;
Expand Down Expand Up @@ -8740,8 +8793,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp, 1);
tg3_netif_start(tp);
if (!tg3_restart_hw(tp, 1))
tg3_netif_start(tp);
}

tg3_full_unlock(tp);
Expand Down Expand Up @@ -11699,14 +11752,16 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
tg3_full_lock(tp, 0);

tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp, 1);
if (tg3_restart_hw(tp, 1))
goto out;

tp->timer.expires = jiffies + tp->timer_offset;
add_timer(&tp->timer);

netif_device_attach(dev);
tg3_netif_start(tp);

out:
tg3_full_unlock(tp);
}

Expand All @@ -11733,16 +11788,19 @@ static int tg3_resume(struct pci_dev *pdev)
tg3_full_lock(tp, 0);

tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_init_hw(tp, 1);
err = tg3_restart_hw(tp, 1);
if (err)
goto out;

tp->timer.expires = jiffies + tp->timer_offset;
add_timer(&tp->timer);

tg3_netif_start(tp);

out:
tg3_full_unlock(tp);

return 0;
return err;
}

static struct pci_driver tg3_driver = {
Expand Down
2 changes: 2 additions & 0 deletions include/linux/netfilter_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ struct bridge_skb_cb {
__u32 ipv4;
} daddr;
};

extern int brnf_deferred_hooks;
#endif /* CONFIG_BRIDGE_NETFILTER */

#endif /* __KERNEL__ */
Expand Down
5 changes: 5 additions & 0 deletions net/bridge/br_netfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ static int brnf_filter_vlan_tagged = 1;
#define brnf_filter_vlan_tagged 1
#endif

int brnf_deferred_hooks;
EXPORT_SYMBOL_GPL(brnf_deferred_hooks);

static __be16 inline vlan_proto(const struct sk_buff *skb)
{
return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
Expand Down Expand Up @@ -890,6 +893,8 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
return NF_ACCEPT;
else if (ip->version == 6 && !brnf_call_ip6tables)
return NF_ACCEPT;
else if (!brnf_deferred_hooks)
return NF_ACCEPT;
#endif
if (hook == NF_IP_POST_ROUTING)
return NF_ACCEPT;
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/ip_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
}

/* Remove any debris in the socket control block */
memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));

return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
ip_rcv_finish);
Expand Down
19 changes: 13 additions & 6 deletions net/ipv4/ipmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1578,6 +1578,7 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
cache = ipmr_cache_find(rt->rt_src, rt->rt_dst);

if (cache==NULL) {
struct sk_buff *skb2;
struct net_device *dev;
int vif;

Expand All @@ -1591,12 +1592,18 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
read_unlock(&mrt_lock);
return -ENODEV;
}
skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
skb->nh.iph->ihl = sizeof(struct iphdr)>>2;
skb->nh.iph->saddr = rt->rt_src;
skb->nh.iph->daddr = rt->rt_dst;
skb->nh.iph->version = 0;
err = ipmr_cache_unresolved(vif, skb);
skb2 = skb_clone(skb, GFP_ATOMIC);
if (!skb2) {
read_unlock(&mrt_lock);
return -ENOMEM;
}

skb2->nh.raw = skb_push(skb2, sizeof(struct iphdr));
skb2->nh.iph->ihl = sizeof(struct iphdr)>>2;
skb2->nh.iph->saddr = rt->rt_src;
skb2->nh.iph->daddr = rt->rt_dst;
skb2->nh.iph->version = 0;
err = ipmr_cache_unresolved(vif, skb2);
read_unlock(&mrt_lock);
return err;
}
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/netfilter/ip_conntrack_helper_h323.c
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,7 @@ static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct,
tuple.dst.protonum = IPPROTO_TCP;

exp = __ip_conntrack_expect_find(&tuple);
if (exp->master == ct)
if (exp && exp->master == ct)
return exp;
return NULL;
}
Expand Down
Loading

0 comments on commit 761a126

Please sign in to comment.