From: Bang Nguyen Date: Thu, 15 Aug 2013 16:57:11 +0000 (-0700) Subject: RDS: ActiveBonding IP exclusion filter X-Git-Tag: v4.1.12-92~293^2^2~47 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f8b77e930a4a14a0534d8d237bfcb3dbf8683e7c;p=users%2Fjedix%2Flinux-maple.git RDS: ActiveBonding IP exclusion filter Define a set of Exclusion IPs that RDS ActiveBond should not manage. This is required to ensure that RDS AB can coexist with other HA IP daemons.. New parameter rds_ib_active_bonding_excl_ips was added to filter out IPs not managed by ActiveBonding. Syntax: rds_ib_active_bonding_excl_ips=[/][,/]* Default: rds_ib_active_bonding_excl_ips=169.254/16,172.10/16 Orabug: 17075950 Signed-off-by: Richard Frank (cherry picked from commit 477e03cf1c378d3a37ec9fa586912d69397b35be) --- diff --git a/net/rds/ib.c b/net/rds/ib.c index 287945d9d83ca..0acf30cc636f3 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -68,6 +68,7 @@ unsigned int rds_ib_cq_balance_enabled = 1; #endif static char *rds_ib_active_bonding_failover_groups = NULL; unsigned int rds_ib_active_bonding_arps = RDS_IB_DEFAULT_NUM_ARPS; +static char *rds_ib_active_bonding_excl_ips = "169.254/16,172.10/16"; module_param(rds_ib_fmr_1m_pool_size, int, 0444); MODULE_PARM_DESC(rds_ib_fmr_1m_pool_size, " Max number of 1m fmr per HCA"); @@ -104,6 +105,9 @@ MODULE_PARM_DESC(rds_ib_cq_balance_enabled, " CQ load balance Enabled"); #endif module_param(rds_ib_active_bonding_arps, int, 0444); MODULE_PARM_DESC(rds_ib_active_bonding_arps, " Num ARPs to be sent when IP moved"); +module_param(rds_ib_active_bonding_excl_ips, charp, 0444); +MODULE_PARM_DESC(rds_ib_active_bonding_excl_ips, + "[/][,/]*"); /* * we have a clumsy combination of RCU and a rwsem protecting this list @@ -125,6 +129,9 @@ static struct rds_ib_port *ip_config; static u8 ip_port_cnt = 0; static u8 ip_port_max = RDS_IB_MAX_PORTS; +static struct rds_ib_excl_ips excl_ips_tbl[RDS_IB_MAX_EXCL_IPS]; +static u8 excl_ips_cnt = 0; + void rds_ib_nodev_connect(void) { struct rds_ib_connection *ic; @@ -844,15 +851,27 @@ static void rds_ib_set_port(struct rds_ib_device *rds_ibdev, __be32 ip_bcast, __be32 ip_mask) { - unsigned int idx; + unsigned int idx, i; + __be32 excl_addr = 0; + + for (i = 0; i < excl_ips_cnt; i++) { + if (!((excl_ips_tbl[i].ip ^ ip_addr) & + excl_ips_tbl[i].mask)) { + excl_addr = 1; + break; + } + } if (!strcmp(net_dev->name, if_name)) { + if (excl_addr) + ip_addr = ip_bcast = ip_mask = 0; + strcpy(ip_config[port].if_name, if_name); ip_config[port].ip_addr = ip_addr; ip_config[port].ip_bcast = ip_bcast; ip_config[port].ip_mask = ip_mask; ip_config[port].ip_active_port = port; - } else { + } else if (!excl_addr) { idx = ip_config[port].alias_cnt++; strcpy(ip_config[port].aliases[idx].if_name, if_name); ip_config[port].aliases[idx].ip_addr = ip_addr; @@ -1262,6 +1281,103 @@ static int rds_ib_ip_config_init(void) return ret; } +static int rds_ib_excl_ip(char *str) +{ + char *tok, *nxt_tok, *end, *prefix_str; + unsigned int octet_cnt = 0; + unsigned long prefix = 0; + __be32 ip = 0; + + prefix_str = strchr(str, '/'); + if (prefix_str) { + *prefix_str = '\0'; + prefix_str++; + prefix = simple_strtol(prefix_str, &end, 0); + if (*end) { + printk(KERN_WARNING "RDS/IP: Warning: IP prefix " + "%s improperly formatted\n", prefix_str); + goto err; + } else if (prefix > 32) { + printk(KERN_WARNING "RDS/IP: Warning: IP prefix " + "%lu out of range\n", prefix); + goto err; + } else { + tok = str; + while (tok && octet_cnt < 4) { + unsigned long octet; + + nxt_tok = strchr(tok, '.'); + if (nxt_tok) { + *nxt_tok = '\0'; + nxt_tok++; + } + octet = simple_strtoul(tok, &end, 0); + if (*end) { + printk(KERN_WARNING "RDS/IP: Warning: " + "IP octet %s improperly " + " formatted\n", tok); + goto err; + } else if (octet > 255) { + printk(KERN_WARNING "RDS/IP: Warning: " + "IP octet %lu out of range\n", + octet); + goto err; + } else { + ((unsigned char *)&ip)[octet_cnt] = + (unsigned char)octet; + octet_cnt++; + } + tok = nxt_tok; + } + + if (tok) { + printk(KERN_WARNING "RDS/IP: Warning: IP " + "%s is improperly formatted\n", str); + goto err; + } + } + } else { + printk(KERN_WARNING "RDS/IP: Warning: IP prefix not " + "specified\n"); + goto err; + } + + excl_ips_tbl[excl_ips_cnt].ip = ip; + excl_ips_tbl[excl_ips_cnt].prefix = prefix; + excl_ips_tbl[excl_ips_cnt].mask = inet_make_mask(prefix); + + excl_ips_cnt++; + + return 0; +err: + return 1; +} + +void rds_ib_ip_excl_ips_init(void) +{ + char *tok, *nxt_tok; + char str[1024]; + + if (rds_ib_active_bonding_excl_ips == NULL) + return; + + strcpy(str, rds_ib_active_bonding_excl_ips); + + tok = str; + while (tok) { + nxt_tok = strchr(tok, ','); + if (nxt_tok) { + *nxt_tok = '\0'; + nxt_tok++; + } + + if (rds_ib_excl_ip(tok)) + return; + + tok = nxt_tok; + } +} + void rds_ib_ip_failover_groups_init(void) { char *tok, *grp, *nxt_tok, *nxt_grp; @@ -1601,6 +1717,8 @@ int rds_ib_init(void) rds_info_register_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info); + rds_ib_ip_excl_ips_init(); + ret = rds_ib_ip_config_init(); if (ret) { printk(KERN_ERR "RDS/IB: failed to init port\n"); diff --git a/net/rds/ib.h b/net/rds/ib.h index d3dce0ba88891..e3a6c422cbc91 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -292,6 +292,13 @@ struct rds_ib_port { struct rds_ib_alias aliases[RDS_IB_MAX_ALIASES]; }; +#define RDS_IB_MAX_EXCL_IPS 20 +struct rds_ib_excl_ips { + __be32 ip; + __be32 prefix; + __be32 mask; +}; + enum { RDS_IB_PORT_EVENT_IB, RDS_IB_PORT_EVENT_NET,