From: Mukesh Kacker Date: Sat, 31 May 2014 03:14:15 +0000 (-0700) Subject: RDS: active bonding - failover/failback only to matching pkey X-Git-Tag: v4.1.12-92~293^2^2~29 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=6c017fb67e50a2c97604dbb621939b7862807b0a;p=users%2Fjedix%2Flinux-maple.git RDS: active bonding - failover/failback only to matching pkey 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 Signed-off-by: Chien-Hua Yen (cherry picked from commit fa3518c7642293f243e7135336c6c8b25a406b03) --- diff --git a/net/rds/ib.c b/net/rds/ib.c index 9eb6621595b9..78550ab3047e 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -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); diff --git a/net/rds/ib.h b/net/rds/ib.h index da0798a8cf64..2149fcbcdc29 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -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]; };