aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Crosser <Eugene.Crosser@ru.ibm.com>2015-05-18 08:27:55 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-18 12:14:17 -0400
commit0db587b065cb3d0417c4e84be851e787d207e8e0 (patch)
tree2d72c37c650e391963f0a5031e4501fd9666e0d6
parentd3c29a5c3fb81b9e2eef65c9edd3b43e7f7510f2 (diff)
qeth: IFF_PROMISC flag to BRIDGE PORT mode
OSA and HiperSocket devices do not support promiscuous mode proper, but they support "BRIDGE PORT" mode that is functionally similar. This update introduces sysfs attribute that, when set, makes the driver try to "reflect" setting and resetting of the IFF_PROMISC flag on the interface into setting and resetting PRIMARY or SECONDARY bridge port role on the underlying OSA or HiperSocket device. Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com> Signed-off-by: Eugene Crosser <Eugene.Crosser@ru.ibm.com> Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/s390/net/qeth_core.h2
-rw-r--r--drivers/s390/net/qeth_l2_main.c40
-rw-r--r--drivers/s390/net/qeth_l2_sys.c56
3 files changed, 95 insertions, 3 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 3abac028899f..ba974a2e409f 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -175,6 +175,8 @@ struct qeth_sbp_info {
175 __u32 supported_funcs; 175 __u32 supported_funcs;
176 enum qeth_sbp_roles role; 176 enum qeth_sbp_roles role;
177 __u32 hostnotification:1; 177 __u32 hostnotification:1;
178 __u32 reflect_promisc:1;
179 __u32 reflect_promisc_primary:1;
178}; 180};
179 181
180static inline int qeth_is_ipa_supported(struct qeth_ipa_info *ipa, 182static inline int qeth_is_ipa_supported(struct qeth_ipa_info *ipa,
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 1cdefaea866c..0ff926d4d63d 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -683,6 +683,39 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
683 return rc ? -EINVAL : 0; 683 return rc ? -EINVAL : 0;
684} 684}
685 685
686static void qeth_promisc_to_bridge(struct qeth_card *card)
687{
688 struct net_device *dev = card->dev;
689 enum qeth_ipa_promisc_modes promisc_mode;
690 int role;
691 int rc;
692
693 QETH_CARD_TEXT(card, 3, "pmisc2br");
694
695 if (!card->options.sbp.reflect_promisc)
696 return;
697 promisc_mode = (dev->flags & IFF_PROMISC) ? SET_PROMISC_MODE_ON
698 : SET_PROMISC_MODE_OFF;
699 if (promisc_mode == card->info.promisc_mode)
700 return;
701
702 if (promisc_mode == SET_PROMISC_MODE_ON) {
703 if (card->options.sbp.reflect_promisc_primary)
704 role = QETH_SBP_ROLE_PRIMARY;
705 else
706 role = QETH_SBP_ROLE_SECONDARY;
707 } else
708 role = QETH_SBP_ROLE_NONE;
709
710 rc = qeth_bridgeport_setrole(card, role);
711 QETH_DBF_TEXT_(SETUP, 2, "bpm%c%04x",
712 (promisc_mode == SET_PROMISC_MODE_ON) ? '+' : '-', rc);
713 if (!rc) {
714 card->options.sbp.role = role;
715 card->info.promisc_mode = promisc_mode;
716 }
717}
718
686static void qeth_l2_set_multicast_list(struct net_device *dev) 719static void qeth_l2_set_multicast_list(struct net_device *dev)
687{ 720{
688 struct qeth_card *card = dev->ml_priv; 721 struct qeth_card *card = dev->ml_priv;
@@ -704,9 +737,10 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
704 qeth_l2_add_mc(card, ha->addr, 1); 737 qeth_l2_add_mc(card, ha->addr, 1);
705 738
706 spin_unlock_bh(&card->mclock); 739 spin_unlock_bh(&card->mclock);
707 if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE)) 740 if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
708 return; 741 qeth_setadp_promisc_mode(card);
709 qeth_setadp_promisc_mode(card); 742 else
743 qeth_promisc_to_bridge(card);
710} 744}
711 745
712static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) 746static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
diff --git a/drivers/s390/net/qeth_l2_sys.c b/drivers/s390/net/qeth_l2_sys.c
index 6504d48bdd97..a553fbab17fc 100644
--- a/drivers/s390/net/qeth_l2_sys.c
+++ b/drivers/s390/net/qeth_l2_sys.c
@@ -159,10 +159,66 @@ static DEVICE_ATTR(bridge_hostnotify, 0644,
159 qeth_bridgeport_hostnotification_show, 159 qeth_bridgeport_hostnotification_show,
160 qeth_bridgeport_hostnotification_store); 160 qeth_bridgeport_hostnotification_store);
161 161
162static ssize_t qeth_bridgeport_reflect_show(struct device *dev,
163 struct device_attribute *attr, char *buf)
164{
165 struct qeth_card *card = dev_get_drvdata(dev);
166 char *state;
167
168 if (!card)
169 return -EINVAL;
170
171 if (card->options.sbp.reflect_promisc) {
172 if (card->options.sbp.reflect_promisc_primary)
173 state = "primary";
174 else
175 state = "secondary";
176 } else
177 state = "none";
178
179 return sprintf(buf, "%s\n", state);
180}
181
182static ssize_t qeth_bridgeport_reflect_store(struct device *dev,
183 struct device_attribute *attr, const char *buf, size_t count)
184{
185 struct qeth_card *card = dev_get_drvdata(dev);
186 int enable, primary;
187
188 if (!card)
189 return -EINVAL;
190
191 if (sysfs_streq(buf, "none")) {
192 enable = 0;
193 primary = 0;
194 } else if (sysfs_streq(buf, "primary")) {
195 enable = 1;
196 primary = 1;
197 } else if (sysfs_streq(buf, "secondary")) {
198 enable = 1;
199 primary = 0;
200 } else
201 return -EINVAL;
202
203 mutex_lock(&card->conf_mutex);
204
205 card->options.sbp.reflect_promisc = enable;
206 card->options.sbp.reflect_promisc_primary = primary;
207
208 mutex_unlock(&card->conf_mutex);
209
210 return count;
211}
212
213static DEVICE_ATTR(bridge_reflect_promisc, 0644,
214 qeth_bridgeport_reflect_show,
215 qeth_bridgeport_reflect_store);
216
162static struct attribute *qeth_l2_bridgeport_attrs[] = { 217static struct attribute *qeth_l2_bridgeport_attrs[] = {
163 &dev_attr_bridge_role.attr, 218 &dev_attr_bridge_role.attr,
164 &dev_attr_bridge_state.attr, 219 &dev_attr_bridge_state.attr,
165 &dev_attr_bridge_hostnotify.attr, 220 &dev_attr_bridge_hostnotify.attr,
221 &dev_attr_bridge_reflect_promisc.attr,
166 NULL, 222 NULL,
167}; 223};
168 224