]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
RDS: active bonding - failover/failback only to matching pkey
authorMukesh Kacker <mukesh.kacker@oracle.com>
Sat, 31 May 2014 03:14:15 +0000 (20:14 -0700)
committerMukesh Kacker <mukesh.kacker@oracle.com>
Wed, 8 Jul 2015 21:00:00 +0000 (14:00 -0700)
The active bonding code does not take the pkey match into
account for failover/failback of ports.

Support is added so failover/failback happen only to ports
with matching pkeys.

Orabug: 18681364

Signed-off-by: Mukesh Kacker <mukesh.kacker@oracle.com>
Signed-off-by: Chien-Hua Yen <chien.yen@oracle.com>
(cherry picked from commit fa3518c7642293f243e7135336c6c8b25a406b03)

net/rds/ib.c
net/rds/ib.h

index 9eb6621595b938a35ad713622187e3701c2d1a46..78550ab3047e9de798821b46e640123ec81a4d50 100644 (file)
@@ -396,24 +396,30 @@ static int rds_ib_laddr_check(__be32 addr)
        return ret;
 }
 
+/*
+ * Get a failover port for port argument ('port')
+ * based on failover group and pkey match.
+ */
 static u8 rds_ib_get_failover_port(u8 port)
 {
        u8      i;
 
        for (i = 1; i <= ip_port_cnt; i++) {
-               if (i != port &&
-                       ip_config[i].failover_group ==
-                               ip_config[port].failover_group &&
-                       ip_config[i].port_state == RDS_IB_PORT_UP) {
+               if ((i != port) &&
+                   (ip_config[i].failover_group ==
+                    ip_config[port].failover_group) &&
+                   (ip_config[i].pkey == ip_config[port].pkey) &&
+                   (ip_config[i].port_state == RDS_IB_PORT_UP)) {
                        return i;
                }
        }
 
        for (i = 1; i <= ip_port_cnt; i++) {
-               if (i != port &&
-                       ip_config[i].port_state == RDS_IB_PORT_UP) {
-                               return i;
-                       }
+               if ((i != port) &&
+                   (ip_config[i].pkey == ip_config[port].pkey) &&
+                   (ip_config[i].port_state == RDS_IB_PORT_UP)) {
+                       return i;
+               }
        }
 
        return 0;
@@ -824,9 +830,10 @@ out:
 }
 
 static u8 rds_ib_init_port(struct rds_ib_device        *rds_ibdev,
-                               struct net_device       *net_dev,
-                               u8                      port_num,
-                               union ib_gid            gid)
+                          struct net_device    *net_dev,
+                          u8                   port_num,
+                          union ib_gid         gid,
+                          uint16_t             pkey)
 {
        const char *digits = "0123456789";
 
@@ -848,6 +855,7 @@ static u8 rds_ib_init_port(struct rds_ib_device     *rds_ibdev,
        ip_config[ip_port_cnt].ip_active_port = 0;
        strcpy(ip_config[ip_port_cnt].if_name, net_dev->name);
        memcpy(&ip_config[ip_port_cnt].gid, &gid, sizeof(union ib_gid));
+       ip_config[ip_port_cnt].pkey = pkey;
 
        if (net_dev->operstate == IF_OPER_UP)
                ip_config[ip_port_cnt].port_state = RDS_IB_PORT_UP;
@@ -1008,12 +1016,23 @@ static void rds_ib_do_failover(u8 from_port, u8 to_port, u8 arp_port,
                if (!to_port) {
                        /* we tried, but did not get a failover port! */
                        rdsdebug("RDS/IP: IP %u.%u.%u.%u failed to "
-                               "migrate from %s: no destination port "
-                               "available!\n",
+                               "migrate from %s: no matching "
+                                "destination port available!\n",
                                 NIPQUAD(ip_config[from_port].ip_addr),
                                 ip_config[from_port].if_name);
                        return;
                }
+       } else {
+               /*
+                * to_port != 0 => caller explicitly specified failover port
+                * validate pkey and flag error if we were passed incorrect
+                * pkey match port. And ignore the request !
+                */
+               if (ip_config[from_port].pkey != ip_config[to_port].pkey) {
+                       printk(KERN_ERR "RDS/IP: port failover request to "
+                              "ports with mismatched pkeys - ignoring request!");
+                       return;
+               }
        }
 
        if (!arp_port)
@@ -1193,29 +1212,33 @@ static void rds_ib_failback(struct work_struct *_work)
                if (ip_config[i].ip_active_port == i) {
                        rds_ib_do_failover(i, 0, ip_active_port,
                                                work->event_type);
-               } else if (ip_config[i].ip_active_port == port) {
+               } else if ((ip_config[i].ip_active_port == port) &&
+                          (ip_config[i].pkey == ip_config[port].pkey)) {
                        rds_ib_do_failover(i, port, ip_active_port,
-                                               work->event_type);
+                                          work->event_type);
                } else if (ip_config[ip_config[i].ip_active_port].port_state ==
-                               RDS_IB_PORT_DOWN) {
+                          RDS_IB_PORT_DOWN) {
                        rds_ib_do_failover(i, 0, ip_active_port,
-                                               work->event_type);
-               } else if (ip_config[port].failover_group ==
-                               ip_config[i].failover_group) {
+                                          work->event_type);
+               } else if ((ip_config[port].failover_group ==
+                               ip_config[i].failover_group) &&
+                          (ip_config[i].pkey == ip_config[port].pkey)) {
                        rds_ib_do_failover(i, port, ip_active_port,
-                                               work->event_type);
+                                          work->event_type);
                }
        }
 
        if (ip_active_port != ip_config[port].ip_active_port) {
                for (i = 1; i <= ip_port_cnt; i++) {
                        if (ip_config[i].port_state == RDS_IB_PORT_DOWN &&
-                               i != ip_active_port && ip_config[i].ip_addr &&
-                               ip_config[i].ip_active_port == ip_active_port) {
+                           i != ip_active_port && ip_config[i].ip_addr &&
+                           ip_config[i].ip_active_port == ip_active_port &&
+                           ip_config[i].pkey ==
+                           ip_config[ip_active_port].pkey) {
 
                                rds_ib_do_failover(i, ip_active_port,
-                                                       ip_active_port,
-                                                       work->event_type);
+                                                  ip_active_port,
+                                                  work->event_type);
                        }
                }
        }
@@ -1348,6 +1371,22 @@ static void rds_ib_dump_ip_config(void)
        }
 }
 
+/*
+ * Parse device name to extract pkey
+ */
+static uint16_t
+get_netdev_pkey(struct net_device *dev)
+{
+       uint16_t pkey = 0;
+       int ibdevnum = -1;
+
+       if (sscanf(dev->name, "ib%d.%04hx", &ibdevnum, &pkey) == 2)
+               return pkey;
+       else
+               return 0xffff;  /* default pkey value! */
+}
+
+
 static int rds_ib_ip_config_init(void)
 {
        struct net_device       *dev;
@@ -1380,6 +1419,8 @@ static int rds_ib_ip_config_init(void)
                        !(dev->flags & IFF_SLAVE) &&
                        !(dev->flags & IFF_MASTER) &&
                        in_dev) {
+                       uint16_t pkey = get_netdev_pkey(dev);
+
                        memcpy(&gid, dev->dev_addr + 4, sizeof gid);
 
                        list_for_each_entry_rcu(rds_ibdev,
@@ -1396,7 +1437,7 @@ static int rds_ib_ip_config_init(void)
                                        RDS_IB_GID_ARG(gid));
                        } else {
                                port = rds_ib_init_port(rds_ibdev, dev,
-                                       port_num, gid);
+                                                       port_num, gid, pkey);
                                if (port > 0) {
                                        for (ifap = &in_dev->ifa_list;
                                                (ifa = *ifap);
@@ -1753,6 +1794,8 @@ static void rds_ib_joining_ip(struct work_struct *_work)
                work->timeout -= msecs_to_jiffies(100);
                queue_delayed_work(rds_wq, &work->work, msecs_to_jiffies(100));
        } else if (in_dev && in_dev->ifa_list) {
+               uint16_t pkey = get_netdev_pkey(ndev);
+
                memcpy(&gid, ndev->dev_addr + 4, sizeof gid);
                list_for_each_entry_rcu(rds_ibdev,
                                &rds_ib_devices, list) {
@@ -1767,7 +1810,7 @@ static void rds_ib_joining_ip(struct work_struct *_work)
                                        RDS_IB_GID_ARG(gid));
                } else {
                        port = rds_ib_init_port(rds_ibdev, ndev,
-                                       port_num, gid);
+                                               port_num, gid, pkey);
                        if (port > 0) {
                                for (ifap = &in_dev->ifa_list;
                                                (ifa = *ifap);
index da0798a8cf645c79e53eca2ea58ded4cccd2c3b4..2149fcbcdc296c54b2698cd91d160e75294b693c 100644 (file)
@@ -296,6 +296,7 @@ struct rds_ib_port {
        __be32                  ip_bcast;
        __be32                  ip_mask;
        unsigned int            ip_active_port;
+       uint16_t                pkey;
        unsigned int            alias_cnt;
        struct rds_ib_alias     aliases[RDS_IB_MAX_ALIASES];
 };