Commit:     74b885cf86def9bc836772e3c1788c00b72a35c9
Parent:     bfafb26e11849fe99e03cc1902a91f7f65354e47
Author:     Florian Zumbiehl <[EMAIL PROTECTED]>
AuthorDate: Fri Apr 20 16:57:27 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Wed Apr 25 22:29:19 2007 -0700

    [PPPOE]: race between interface going down and connect()
    below you find a patch that (hopefully) fixes a race between an interface
    going down and a connect() to a peer on that interface. Before,
    connect() would determine that an interface is up, then the interface
    could go down and all entries referring to that interface in the
    item_hash_table would be marked as ZOMBIEs and their references to
    the device would be freed, and after that, connect() would put a new
    entry into the hash table referring to the device that meanwhile is
    down already - which also would cause unregister_netdevice() to wait
    until the socket has been release()d.
    This patch does not suffice if we are not allowed to accept connect()s
    referring to a device that we already acked a NETDEV_GOING_DOWN for
    (that is: all references are only guaranteed to be freed after
    NETDEV_DOWN has been acknowledged, not necessarily after the
    NETDEV_GOING_DOWN already). And if we are allowed to, we could avoid
    looking through the hash table upon NETDEV_GOING_DOWN completely and
    only do that once we get the NETDEV_DOWN ...
    pppoe_flush_dev is called on NETDEV_GOING_DOWN and NETDEV_DOWN to deal with
    this "late connect" issue.  Ideally one would hope to notify users at the
    "NETDEV_GOING_DOWN" phase (just to pretend to be nice).  However, it is the
    NETDEV_DOWN scan that takes all the responsibility for ensuring nobody is
    hanging around at that time.
    Signed-off-by: Florian Zumbiehl <[EMAIL PROTECTED]>
    Acked-by: Michal Ostrowski <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
 drivers/net/pppoe.c |   19 ++++++-------------
 1 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index f761a9a..bc4fc30 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -218,17 +218,6 @@ static inline struct pppox_sock *get_item_by_addr(struct 
sockaddr_pppox *sp)
        return get_item(sp->sa_addr.pppoe.sid, sp->sa_addr.pppoe.remote, 
-static inline int set_item(struct pppox_sock *po)
-       int i;
-       write_lock_bh(&pppoe_hash_lock);
-       i = __set_item(po);
-       write_unlock_bh(&pppoe_hash_lock);
-       return i;
 static inline struct pppox_sock *delete_item(unsigned long sid, char *addr, 
int ifindex)
        struct pppox_sock *ret;
@@ -595,14 +584,18 @@ static int pppoe_connect(struct socket *sock, struct 
sockaddr *uservaddr,
                po->pppoe_dev = dev;
                po->pppoe_ifindex = dev->ifindex;
-               if (!(dev->flags & IFF_UP))
+               write_lock_bh(&pppoe_hash_lock);
+               if (!(dev->flags & IFF_UP)){
+                       write_unlock_bh(&pppoe_hash_lock);
                        goto err_put;
+               }
                       sizeof(struct pppoe_addr));
-               error = set_item(po);
+               error = __set_item(po);
+               write_unlock_bh(&pppoe_hash_lock);
                if (error < 0)
                        goto err_put;
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at

Reply via email to