lkml.org 
[lkml]   [2018]   [Jan]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 56/75] s390/qeth: update takeover IPs after configuration change
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

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

    From: Julian Wiedmann <jwi@linux.vnet.ibm.com>


    [ Upstream commit 02f510f326501470348a5df341e8232c3497bbbb ]

    Any modification to the takeover IP-ranges requires that we re-evaluate
    which IP addresses are takeover-eligible. Otherwise we might do takeover
    for some addresses when we no longer should, or vice-versa.

    Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/s390/net/qeth_core.h | 4 +-
    drivers/s390/net/qeth_core_main.c | 4 +-
    drivers/s390/net/qeth_l3.h | 2 -
    drivers/s390/net/qeth_l3_main.c | 31 ++++++++++++++++--
    drivers/s390/net/qeth_l3_sys.c | 63 ++++++++++++++++++++------------------
    5 files changed, 67 insertions(+), 37 deletions(-)

    --- a/drivers/s390/net/qeth_core.h
    +++ b/drivers/s390/net/qeth_core.h
    @@ -577,8 +577,8 @@ enum qeth_cq {

    struct qeth_ipato {
    bool enabled;
    - int invert4;
    - int invert6;
    + bool invert4;
    + bool invert6;
    struct list_head entries;
    };

    --- a/drivers/s390/net/qeth_core_main.c
    +++ b/drivers/s390/net/qeth_core_main.c
    @@ -1476,8 +1476,8 @@ static int qeth_setup_card(struct qeth_c
    /* IP address takeover */
    INIT_LIST_HEAD(&card->ipato.entries);
    card->ipato.enabled = false;
    - card->ipato.invert4 = 0;
    - card->ipato.invert6 = 0;
    + card->ipato.invert4 = false;
    + card->ipato.invert6 = false;
    /* init QDIO stuff */
    qeth_init_qdio_info(card);
    INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work);
    --- a/drivers/s390/net/qeth_l3.h
    +++ b/drivers/s390/net/qeth_l3.h
    @@ -80,7 +80,7 @@ void qeth_l3_del_vipa(struct qeth_card *
    int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
    void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
    const u8 *);
    -int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
    +void qeth_l3_update_ipato(struct qeth_card *card);
    struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions);
    int qeth_l3_add_ip(struct qeth_card *, struct qeth_ipaddr *);
    int qeth_l3_delete_ip(struct qeth_card *, struct qeth_ipaddr *);
    --- a/drivers/s390/net/qeth_l3_main.c
    +++ b/drivers/s390/net/qeth_l3_main.c
    @@ -168,8 +168,8 @@ static void qeth_l3_convert_addr_to_bits
    }
    }

    -int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
    - struct qeth_ipaddr *addr)
    +static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
    + struct qeth_ipaddr *addr)
    {
    struct qeth_ipato_entry *ipatoe;
    u8 addr_bits[128] = {0, };
    @@ -608,6 +608,27 @@ int qeth_l3_setrouting_v6(struct qeth_ca
    /*
    * IP address takeover related functions
    */
    +
    +/**
    + * qeth_l3_update_ipato() - Update 'takeover' property, for all NORMAL IPs.
    + *
    + * Caller must hold ip_lock.
    + */
    +void qeth_l3_update_ipato(struct qeth_card *card)
    +{
    + struct qeth_ipaddr *addr;
    + unsigned int i;
    +
    + hash_for_each(card->ip_htable, i, addr, hnode) {
    + if (addr->type != QETH_IP_TYPE_NORMAL)
    + continue;
    + if (qeth_l3_is_addr_covered_by_ipato(card, addr))
    + addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
    + else
    + addr->set_flags &= ~QETH_IPA_SETIP_TAKEOVER_FLAG;
    + }
    +}
    +
    static void qeth_l3_clear_ipato_list(struct qeth_card *card)
    {
    struct qeth_ipato_entry *ipatoe, *tmp;
    @@ -619,6 +640,7 @@ static void qeth_l3_clear_ipato_list(str
    kfree(ipatoe);
    }

    + qeth_l3_update_ipato(card);
    spin_unlock_bh(&card->ip_lock);
    }

    @@ -643,8 +665,10 @@ int qeth_l3_add_ipato_entry(struct qeth_
    }
    }

    - if (!rc)
    + if (!rc) {
    list_add_tail(&new->entry, &card->ipato.entries);
    + qeth_l3_update_ipato(card);
    + }

    spin_unlock_bh(&card->ip_lock);

    @@ -667,6 +691,7 @@ void qeth_l3_del_ipato_entry(struct qeth
    (proto == QETH_PROT_IPV4)? 4:16) &&
    (ipatoe->mask_bits == mask_bits)) {
    list_del(&ipatoe->entry);
    + qeth_l3_update_ipato(card);
    kfree(ipatoe);
    }
    }
    --- a/drivers/s390/net/qeth_l3_sys.c
    +++ b/drivers/s390/net/qeth_l3_sys.c
    @@ -372,9 +372,8 @@ static ssize_t qeth_l3_dev_ipato_enable_
    struct device_attribute *attr, const char *buf, size_t count)
    {
    struct qeth_card *card = dev_get_drvdata(dev);
    - struct qeth_ipaddr *addr;
    - int i, rc = 0;
    bool enable;
    + int rc = 0;

    if (!card)
    return -EINVAL;
    @@ -393,20 +392,12 @@ static ssize_t qeth_l3_dev_ipato_enable_
    goto out;
    }

    - if (card->ipato.enabled == enable)
    - goto out;
    - card->ipato.enabled = enable;
    -
    - spin_lock_bh(&card->ip_lock);
    - hash_for_each(card->ip_htable, i, addr, hnode) {
    - if (addr->type != QETH_IP_TYPE_NORMAL)
    - continue;
    - if (!enable)
    - addr->set_flags &= ~QETH_IPA_SETIP_TAKEOVER_FLAG;
    - else if (qeth_l3_is_addr_covered_by_ipato(card, addr))
    - addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
    + if (card->ipato.enabled != enable) {
    + card->ipato.enabled = enable;
    + spin_lock_bh(&card->ip_lock);
    + qeth_l3_update_ipato(card);
    + spin_unlock_bh(&card->ip_lock);
    }
    - spin_unlock_bh(&card->ip_lock);
    out:
    mutex_unlock(&card->conf_mutex);
    return rc ? rc : count;
    @@ -432,20 +423,27 @@ static ssize_t qeth_l3_dev_ipato_invert4
    const char *buf, size_t count)
    {
    struct qeth_card *card = dev_get_drvdata(dev);
    + bool invert;
    int rc = 0;

    if (!card)
    return -EINVAL;

    mutex_lock(&card->conf_mutex);
    - if (sysfs_streq(buf, "toggle"))
    - card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
    - else if (sysfs_streq(buf, "1"))
    - card->ipato.invert4 = 1;
    - else if (sysfs_streq(buf, "0"))
    - card->ipato.invert4 = 0;
    - else
    + if (sysfs_streq(buf, "toggle")) {
    + invert = !card->ipato.invert4;
    + } else if (kstrtobool(buf, &invert)) {
    rc = -EINVAL;
    + goto out;
    + }
    +
    + if (card->ipato.invert4 != invert) {
    + card->ipato.invert4 = invert;
    + spin_lock_bh(&card->ip_lock);
    + qeth_l3_update_ipato(card);
    + spin_unlock_bh(&card->ip_lock);
    + }
    +out:
    mutex_unlock(&card->conf_mutex);
    return rc ? rc : count;
    }
    @@ -611,20 +609,27 @@ static ssize_t qeth_l3_dev_ipato_invert6
    struct device_attribute *attr, const char *buf, size_t count)
    {
    struct qeth_card *card = dev_get_drvdata(dev);
    + bool invert;
    int rc = 0;

    if (!card)
    return -EINVAL;

    mutex_lock(&card->conf_mutex);
    - if (sysfs_streq(buf, "toggle"))
    - card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
    - else if (sysfs_streq(buf, "1"))
    - card->ipato.invert6 = 1;
    - else if (sysfs_streq(buf, "0"))
    - card->ipato.invert6 = 0;
    - else
    + if (sysfs_streq(buf, "toggle")) {
    + invert = !card->ipato.invert6;
    + } else if (kstrtobool(buf, &invert)) {
    rc = -EINVAL;
    + goto out;
    + }
    +
    + if (card->ipato.invert6 != invert) {
    + card->ipato.invert6 = invert;
    + spin_lock_bh(&card->ip_lock);
    + qeth_l3_update_ipato(card);
    + spin_unlock_bh(&card->ip_lock);
    + }
    +out:
    mutex_unlock(&card->conf_mutex);
    return rc ? rc : count;
    }

    \
     
     \ /
      Last update: 2018-01-01 16:15    [W:4.103 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site