From 49384507896ee26e67266cebef6b6a9f2e31081c Mon Sep 17 00:00:00 2001 From: Allan Stephens Date: Sun, 25 Jun 2006 23:38:29 -0700 Subject: [TIPC]: Corrected potential misuse of tipc_media_addr structure. Signed-off-by: Allan Stephens Signed-off-by: Per Liden Signed-off-by: David S. Miller --- include/net/tipc/tipc_bearer.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/net/tipc/tipc_bearer.h b/include/net/tipc/tipc_bearer.h index 098607cd4b78..e07136d74c2f 100644 --- a/include/net/tipc/tipc_bearer.h +++ b/include/net/tipc/tipc_bearer.h @@ -49,10 +49,18 @@ #define TIPC_MEDIA_TYPE_ETH 1 +/* + * Destination address structure used by TIPC bearers when sending messages + * + * IMPORTANT: The fields of this structure MUST be stored using the specified + * byte order indicated below, as the structure is exchanged between nodes + * as part of a link setup process. + */ + struct tipc_media_addr { - __u32 type; + __u32 type; /* bearer type (network byte order) */ union { - __u8 eth_addr[6]; /* Ethernet bearer */ + __u8 eth_addr[6]; /* 48 bit Ethernet addr (byte array) */ #if 0 /* Prototypes for other possible bearer types */ -- cgit v1.2.3 From 6048126440dcb3ba01316f961465c0ff5a255dd1 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 25 Jun 2006 23:58:10 -0700 Subject: [NET]: make net/core/dev.c:netdev_nit static netdev_nit can now become static. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller --- include/linux/netdevice.h | 1 - net/core/dev.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index bc747e5d7138..03cd7551a7a1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -699,7 +699,6 @@ extern int dev_hard_start_xmit(struct sk_buff *skb, extern void dev_init(void); -extern int netdev_nit; extern int netdev_budget; /* Called by rtnetlink.c:rtnl_unlock() */ diff --git a/net/core/dev.c b/net/core/dev.c index aa8454901719..f1c52cbd6ef7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -230,7 +230,7 @@ extern void netdev_unregister_sysfs(struct net_device *); * For efficiency */ -int netdev_nit; +static int netdev_nit; /* * Add a protocol ID to the list. Now that the input handler is -- cgit v1.2.3 From 068c6e98bc7ec4419299b38cd40be26ebf4bdeda Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 26 Jun 2006 00:04:27 -0700 Subject: [NET] netpoll: break recursive loop in netpoll rx path The netpoll system currently has a rx to tx path via: netpoll_rx __netpoll_rx arp_reply netpoll_send_skb dev->hard_start_tx This rx->tx loop places network drivers at risk of inadvertently causing a deadlock or BUG halt by recursively trying to acquire a spinlock that is used in both their rx and tx paths (this problem was origionally reported to me in the 3c59x driver, which shares a spinlock between the boomerang_interrupt and boomerang_start_xmit routines). This patch breaks this loop, by queueing arp frames, so that they can be responded to after all receive operations have been completed. Tested by myself and the reported with successful results. Specifically it was tested with netdump. Heres the BZ with details: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=194055 Signed-off-by: Neil Horman Acked-by: Matt Mackall Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/linux/netpoll.h | 1 + net/core/netpoll.c | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index ca5a8733000f..1efe60c5c00c 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -31,6 +31,7 @@ struct netpoll_info { int rx_flags; spinlock_t rx_lock; struct netpoll *rx_np; /* netpoll that registered an rx_hook */ + struct sk_buff_head arp_tx; /* list of arp requests to reply to */ }; void netpoll_poll(struct netpoll *np); diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 377d1e7257b5..471da451cd48 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -54,6 +54,7 @@ static atomic_t trapped; sizeof(struct iphdr) + sizeof(struct ethhdr)) static void zap_completion_queue(void); +static void arp_reply(struct sk_buff *skb); static void queue_process(void *p) { @@ -153,6 +154,22 @@ static void poll_napi(struct netpoll *np) } } +static void service_arp_queue(struct netpoll_info *npi) +{ + struct sk_buff *skb; + + if (unlikely(!npi)) + return; + + skb = skb_dequeue(&npi->arp_tx); + + while (skb != NULL) { + arp_reply(skb); + skb = skb_dequeue(&npi->arp_tx); + } + return; +} + void netpoll_poll(struct netpoll *np) { if(!np->dev || !netif_running(np->dev) || !np->dev->poll_controller) @@ -163,6 +180,8 @@ void netpoll_poll(struct netpoll *np) if (np->dev->poll) poll_napi(np); + service_arp_queue(np->dev->npinfo); + zap_completion_queue(); } @@ -442,7 +461,9 @@ int __netpoll_rx(struct sk_buff *skb) int proto, len, ulen; struct iphdr *iph; struct udphdr *uh; - struct netpoll *np = skb->dev->npinfo->rx_np; + struct netpoll_info *npi = skb->dev->npinfo; + struct netpoll *np = npi->rx_np; + if (!np) goto out; @@ -452,7 +473,7 @@ int __netpoll_rx(struct sk_buff *skb) /* check if netpoll clients need ARP */ if (skb->protocol == __constant_htons(ETH_P_ARP) && atomic_read(&trapped)) { - arp_reply(skb); + skb_queue_tail(&npi->arp_tx, skb); return 1; } @@ -647,6 +668,7 @@ int netpoll_setup(struct netpoll *np) npinfo->poll_owner = -1; npinfo->tries = MAX_RETRIES; spin_lock_init(&npinfo->rx_lock); + skb_queue_head_init(&npinfo->arp_tx); } else npinfo = ndev->npinfo; -- cgit v1.2.3