xref: /linux/drivers/s390/net/qeth_l3_sys.c (revision 132db93572821ec2fdf81e354cc40f558faf7e4f)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *    Copyright IBM Corp. 2007
4  *    Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
5  *		 Frank Pavlic <fpavlic@de.ibm.com>,
6  *		 Thomas Spatzier <tspat@de.ibm.com>,
7  *		 Frank Blaschka <frank.blaschka@de.ibm.com>
8  */
9 
10 #include <linux/slab.h>
11 #include <asm/ebcdic.h>
12 #include <linux/hashtable.h>
13 #include <linux/inet.h>
14 #include "qeth_l3.h"
15 
16 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
17 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
18 
19 static int qeth_l3_string_to_ipaddr(const char *buf,
20 				    enum qeth_prot_versions proto, u8 *addr)
21 {
22 	const char *end;
23 
24 	if ((proto == QETH_PROT_IPV4 && !in4_pton(buf, -1, addr, -1, &end)) ||
25 	    (proto == QETH_PROT_IPV6 && !in6_pton(buf, -1, addr, -1, &end)))
26 		return -EINVAL;
27 	return 0;
28 }
29 
30 static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
31 			struct qeth_routing_info *route, char *buf)
32 {
33 	switch (route->type) {
34 	case PRIMARY_ROUTER:
35 		return sprintf(buf, "%s\n", "primary router");
36 	case SECONDARY_ROUTER:
37 		return sprintf(buf, "%s\n", "secondary router");
38 	case MULTICAST_ROUTER:
39 		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
40 			return sprintf(buf, "%s\n", "multicast router+");
41 		else
42 			return sprintf(buf, "%s\n", "multicast router");
43 	case PRIMARY_CONNECTOR:
44 		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
45 			return sprintf(buf, "%s\n", "primary connector+");
46 		else
47 			return sprintf(buf, "%s\n", "primary connector");
48 	case SECONDARY_CONNECTOR:
49 		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
50 			return sprintf(buf, "%s\n", "secondary connector+");
51 		else
52 			return sprintf(buf, "%s\n", "secondary connector");
53 	default:
54 		return sprintf(buf, "%s\n", "no");
55 	}
56 }
57 
58 static ssize_t qeth_l3_dev_route4_show(struct device *dev,
59 			struct device_attribute *attr, char *buf)
60 {
61 	struct qeth_card *card = dev_get_drvdata(dev);
62 
63 	return qeth_l3_dev_route_show(card, &card->options.route4, buf);
64 }
65 
66 static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
67 		struct qeth_routing_info *route, enum qeth_prot_versions prot,
68 		const char *buf, size_t count)
69 {
70 	enum qeth_routing_types old_route_type = route->type;
71 	int rc = 0;
72 
73 	mutex_lock(&card->conf_mutex);
74 	if (sysfs_streq(buf, "no_router")) {
75 		route->type = NO_ROUTER;
76 	} else if (sysfs_streq(buf, "primary_connector")) {
77 		route->type = PRIMARY_CONNECTOR;
78 	} else if (sysfs_streq(buf, "secondary_connector")) {
79 		route->type = SECONDARY_CONNECTOR;
80 	} else if (sysfs_streq(buf, "primary_router")) {
81 		route->type = PRIMARY_ROUTER;
82 	} else if (sysfs_streq(buf, "secondary_router")) {
83 		route->type = SECONDARY_ROUTER;
84 	} else if (sysfs_streq(buf, "multicast_router")) {
85 		route->type = MULTICAST_ROUTER;
86 	} else {
87 		rc = -EINVAL;
88 		goto out;
89 	}
90 	if (qeth_card_hw_is_reachable(card) &&
91 	    (old_route_type != route->type)) {
92 		if (prot == QETH_PROT_IPV4)
93 			rc = qeth_l3_setrouting_v4(card);
94 		else if (prot == QETH_PROT_IPV6)
95 			rc = qeth_l3_setrouting_v6(card);
96 	}
97 out:
98 	if (rc)
99 		route->type = old_route_type;
100 	mutex_unlock(&card->conf_mutex);
101 	return rc ? rc : count;
102 }
103 
104 static ssize_t qeth_l3_dev_route4_store(struct device *dev,
105 		struct device_attribute *attr, const char *buf, size_t count)
106 {
107 	struct qeth_card *card = dev_get_drvdata(dev);
108 
109 	return qeth_l3_dev_route_store(card, &card->options.route4,
110 				QETH_PROT_IPV4, buf, count);
111 }
112 
113 static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
114 			qeth_l3_dev_route4_store);
115 
116 static ssize_t qeth_l3_dev_route6_show(struct device *dev,
117 			struct device_attribute *attr, char *buf)
118 {
119 	struct qeth_card *card = dev_get_drvdata(dev);
120 
121 	return qeth_l3_dev_route_show(card, &card->options.route6, buf);
122 }
123 
124 static ssize_t qeth_l3_dev_route6_store(struct device *dev,
125 		struct device_attribute *attr, const char *buf, size_t count)
126 {
127 	struct qeth_card *card = dev_get_drvdata(dev);
128 
129 	return qeth_l3_dev_route_store(card, &card->options.route6,
130 				QETH_PROT_IPV6, buf, count);
131 }
132 
133 static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
134 			qeth_l3_dev_route6_store);
135 
136 static ssize_t qeth_l3_dev_sniffer_show(struct device *dev,
137 		struct device_attribute *attr, char *buf)
138 {
139 	struct qeth_card *card = dev_get_drvdata(dev);
140 
141 	return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0);
142 }
143 
144 static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
145 		struct device_attribute *attr, const char *buf, size_t count)
146 {
147 	struct qeth_card *card = dev_get_drvdata(dev);
148 	int rc = 0;
149 	unsigned long i;
150 
151 	if (!IS_IQD(card))
152 		return -EPERM;
153 	if (card->options.cq == QETH_CQ_ENABLED)
154 		return -EPERM;
155 
156 	mutex_lock(&card->conf_mutex);
157 	if (card->state != CARD_STATE_DOWN) {
158 		rc = -EPERM;
159 		goto out;
160 	}
161 
162 	rc = kstrtoul(buf, 16, &i);
163 	if (rc) {
164 		rc = -EINVAL;
165 		goto out;
166 	}
167 	switch (i) {
168 	case 0:
169 		card->options.sniffer = i;
170 		break;
171 	case 1:
172 		qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd);
173 		if (card->ssqd.qdioac2 & CHSC_AC2_SNIFFER_AVAILABLE) {
174 			card->options.sniffer = i;
175 			qeth_resize_buffer_pool(card, QETH_IN_BUF_COUNT_MAX);
176 		} else {
177 			rc = -EPERM;
178 		}
179 
180 		break;
181 	default:
182 		rc = -EINVAL;
183 	}
184 out:
185 	mutex_unlock(&card->conf_mutex);
186 	return rc ? rc : count;
187 }
188 
189 static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show,
190 		qeth_l3_dev_sniffer_store);
191 
192 static ssize_t qeth_l3_dev_hsuid_show(struct device *dev,
193 		struct device_attribute *attr, char *buf)
194 {
195 	struct qeth_card *card = dev_get_drvdata(dev);
196 	char tmp_hsuid[9];
197 
198 	if (!IS_IQD(card))
199 		return -EPERM;
200 
201 	memcpy(tmp_hsuid, card->options.hsuid, sizeof(tmp_hsuid));
202 	EBCASC(tmp_hsuid, 8);
203 	return sprintf(buf, "%s\n", tmp_hsuid);
204 }
205 
206 static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
207 		struct device_attribute *attr, const char *buf, size_t count)
208 {
209 	struct qeth_card *card = dev_get_drvdata(dev);
210 	int rc = 0;
211 	char *tmp;
212 
213 	if (!IS_IQD(card))
214 		return -EPERM;
215 
216 	mutex_lock(&card->conf_mutex);
217 	if (card->state != CARD_STATE_DOWN) {
218 		rc = -EPERM;
219 		goto out;
220 	}
221 
222 	if (card->options.sniffer) {
223 		rc = -EPERM;
224 		goto out;
225 	}
226 
227 	if (card->options.cq == QETH_CQ_NOTAVAILABLE) {
228 		rc = -EPERM;
229 		goto out;
230 	}
231 
232 	tmp = strsep((char **)&buf, "\n");
233 	if (strlen(tmp) > 8) {
234 		rc = -EINVAL;
235 		goto out;
236 	}
237 
238 	if (card->options.hsuid[0])
239 		/* delete old ip address */
240 		qeth_l3_modify_hsuid(card, false);
241 
242 	if (strlen(tmp) == 0) {
243 		/* delete ip address only */
244 		card->options.hsuid[0] = '\0';
245 		memcpy(card->dev->perm_addr, card->options.hsuid, 9);
246 		qeth_configure_cq(card, QETH_CQ_DISABLED);
247 		goto out;
248 	}
249 
250 	if (qeth_configure_cq(card, QETH_CQ_ENABLED)) {
251 		rc = -EPERM;
252 		goto out;
253 	}
254 
255 	snprintf(card->options.hsuid, sizeof(card->options.hsuid),
256 		 "%-8s", tmp);
257 	ASCEBC(card->options.hsuid, 8);
258 	memcpy(card->dev->perm_addr, card->options.hsuid, 9);
259 
260 	rc = qeth_l3_modify_hsuid(card, true);
261 
262 out:
263 	mutex_unlock(&card->conf_mutex);
264 	return rc ? rc : count;
265 }
266 
267 static DEVICE_ATTR(hsuid, 0644, qeth_l3_dev_hsuid_show,
268 		   qeth_l3_dev_hsuid_store);
269 
270 
271 static struct attribute *qeth_l3_device_attrs[] = {
272 	&dev_attr_route4.attr,
273 	&dev_attr_route6.attr,
274 	&dev_attr_sniffer.attr,
275 	&dev_attr_hsuid.attr,
276 	NULL,
277 };
278 
279 static const struct attribute_group qeth_l3_device_attr_group = {
280 	.attrs = qeth_l3_device_attrs,
281 };
282 
283 static ssize_t qeth_l3_dev_ipato_enable_show(struct device *dev,
284 			struct device_attribute *attr, char *buf)
285 {
286 	struct qeth_card *card = dev_get_drvdata(dev);
287 
288 	return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
289 }
290 
291 static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
292 		struct device_attribute *attr, const char *buf, size_t count)
293 {
294 	struct qeth_card *card = dev_get_drvdata(dev);
295 	bool enable;
296 	int rc = 0;
297 
298 	mutex_lock(&card->conf_mutex);
299 	if (card->state != CARD_STATE_DOWN) {
300 		rc = -EPERM;
301 		goto out;
302 	}
303 
304 	if (sysfs_streq(buf, "toggle")) {
305 		enable = !card->ipato.enabled;
306 	} else if (kstrtobool(buf, &enable)) {
307 		rc = -EINVAL;
308 		goto out;
309 	}
310 
311 	if (card->ipato.enabled != enable) {
312 		card->ipato.enabled = enable;
313 		mutex_lock(&card->ip_lock);
314 		qeth_l3_update_ipato(card);
315 		mutex_unlock(&card->ip_lock);
316 	}
317 out:
318 	mutex_unlock(&card->conf_mutex);
319 	return rc ? rc : count;
320 }
321 
322 static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
323 			qeth_l3_dev_ipato_enable_show,
324 			qeth_l3_dev_ipato_enable_store);
325 
326 static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
327 				struct device_attribute *attr, char *buf)
328 {
329 	struct qeth_card *card = dev_get_drvdata(dev);
330 
331 	return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
332 }
333 
334 static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
335 				struct device_attribute *attr,
336 				const char *buf, size_t count)
337 {
338 	struct qeth_card *card = dev_get_drvdata(dev);
339 	bool invert;
340 	int rc = 0;
341 
342 	mutex_lock(&card->conf_mutex);
343 	if (sysfs_streq(buf, "toggle")) {
344 		invert = !card->ipato.invert4;
345 	} else if (kstrtobool(buf, &invert)) {
346 		rc = -EINVAL;
347 		goto out;
348 	}
349 
350 	if (card->ipato.invert4 != invert) {
351 		card->ipato.invert4 = invert;
352 		mutex_lock(&card->ip_lock);
353 		qeth_l3_update_ipato(card);
354 		mutex_unlock(&card->ip_lock);
355 	}
356 out:
357 	mutex_unlock(&card->conf_mutex);
358 	return rc ? rc : count;
359 }
360 
361 static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
362 			qeth_l3_dev_ipato_invert4_show,
363 			qeth_l3_dev_ipato_invert4_store);
364 
365 static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
366 			enum qeth_prot_versions proto)
367 {
368 	struct qeth_ipato_entry *ipatoe;
369 	int str_len = 0;
370 
371 	mutex_lock(&card->ip_lock);
372 	list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
373 		char addr_str[40];
374 		int entry_len;
375 
376 		if (ipatoe->proto != proto)
377 			continue;
378 
379 		entry_len = qeth_l3_ipaddr_to_string(proto, ipatoe->addr,
380 						     addr_str);
381 		if (entry_len < 0)
382 			continue;
383 
384 		/* Append /%mask to the entry: */
385 		entry_len += 1 + ((proto == QETH_PROT_IPV4) ? 2 : 3);
386 		/* Enough room to format %entry\n into null terminated page? */
387 		if (entry_len + 1 > PAGE_SIZE - str_len - 1)
388 			break;
389 
390 		entry_len = scnprintf(buf, PAGE_SIZE - str_len,
391 				      "%s/%i\n", addr_str, ipatoe->mask_bits);
392 		str_len += entry_len;
393 		buf += entry_len;
394 	}
395 	mutex_unlock(&card->ip_lock);
396 
397 	return str_len ? str_len : scnprintf(buf, PAGE_SIZE, "\n");
398 }
399 
400 static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
401 				struct device_attribute *attr, char *buf)
402 {
403 	struct qeth_card *card = dev_get_drvdata(dev);
404 
405 	return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
406 }
407 
408 static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
409 		  u8 *addr, int *mask_bits)
410 {
411 	const char *start, *end;
412 	char *tmp;
413 	char buffer[40] = {0, };
414 
415 	start = buf;
416 	/* get address string */
417 	end = strchr(start, '/');
418 	if (!end || (end - start >= 40)) {
419 		return -EINVAL;
420 	}
421 	strncpy(buffer, start, end - start);
422 	if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
423 		return -EINVAL;
424 	}
425 	start = end + 1;
426 	*mask_bits = simple_strtoul(start, &tmp, 10);
427 	if (!strlen(start) ||
428 	    (tmp == start) ||
429 	    (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
430 		return -EINVAL;
431 	}
432 	return 0;
433 }
434 
435 static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
436 			 struct qeth_card *card, enum qeth_prot_versions proto)
437 {
438 	struct qeth_ipato_entry *ipatoe;
439 	u8 addr[16];
440 	int mask_bits;
441 	int rc = 0;
442 
443 	rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
444 	if (rc)
445 		return rc;
446 
447 	ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
448 	if (!ipatoe)
449 		return -ENOMEM;
450 
451 	ipatoe->proto = proto;
452 	memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
453 	ipatoe->mask_bits = mask_bits;
454 
455 	rc = qeth_l3_add_ipato_entry(card, ipatoe);
456 	if (rc)
457 		kfree(ipatoe);
458 
459 	return rc ? rc : count;
460 }
461 
462 static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
463 		struct device_attribute *attr, const char *buf, size_t count)
464 {
465 	struct qeth_card *card = dev_get_drvdata(dev);
466 
467 	return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
468 }
469 
470 static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
471 			qeth_l3_dev_ipato_add4_show,
472 			qeth_l3_dev_ipato_add4_store);
473 
474 static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
475 			 struct qeth_card *card, enum qeth_prot_versions proto)
476 {
477 	u8 addr[16];
478 	int mask_bits;
479 	int rc = 0;
480 
481 	rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
482 	if (!rc)
483 		rc = qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
484 	return rc ? rc : count;
485 }
486 
487 static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
488 		struct device_attribute *attr, const char *buf, size_t count)
489 {
490 	struct qeth_card *card = dev_get_drvdata(dev);
491 
492 	return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
493 }
494 
495 static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
496 			qeth_l3_dev_ipato_del4_store);
497 
498 static ssize_t qeth_l3_dev_ipato_invert6_show(struct device *dev,
499 		struct device_attribute *attr, char *buf)
500 {
501 	struct qeth_card *card = dev_get_drvdata(dev);
502 
503 	return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
504 }
505 
506 static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
507 		struct device_attribute *attr, const char *buf, size_t count)
508 {
509 	struct qeth_card *card = dev_get_drvdata(dev);
510 	bool invert;
511 	int rc = 0;
512 
513 	mutex_lock(&card->conf_mutex);
514 	if (sysfs_streq(buf, "toggle")) {
515 		invert = !card->ipato.invert6;
516 	} else if (kstrtobool(buf, &invert)) {
517 		rc = -EINVAL;
518 		goto out;
519 	}
520 
521 	if (card->ipato.invert6 != invert) {
522 		card->ipato.invert6 = invert;
523 		mutex_lock(&card->ip_lock);
524 		qeth_l3_update_ipato(card);
525 		mutex_unlock(&card->ip_lock);
526 	}
527 out:
528 	mutex_unlock(&card->conf_mutex);
529 	return rc ? rc : count;
530 }
531 
532 static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
533 			qeth_l3_dev_ipato_invert6_show,
534 			qeth_l3_dev_ipato_invert6_store);
535 
536 
537 static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
538 				struct device_attribute *attr, char *buf)
539 {
540 	struct qeth_card *card = dev_get_drvdata(dev);
541 
542 	return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
543 }
544 
545 static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
546 		struct device_attribute *attr, const char *buf, size_t count)
547 {
548 	struct qeth_card *card = dev_get_drvdata(dev);
549 
550 	return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
551 }
552 
553 static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
554 			qeth_l3_dev_ipato_add6_show,
555 			qeth_l3_dev_ipato_add6_store);
556 
557 static ssize_t qeth_l3_dev_ipato_del6_store(struct device *dev,
558 		struct device_attribute *attr, const char *buf, size_t count)
559 {
560 	struct qeth_card *card = dev_get_drvdata(dev);
561 
562 	return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
563 }
564 
565 static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
566 			qeth_l3_dev_ipato_del6_store);
567 
568 static struct attribute *qeth_ipato_device_attrs[] = {
569 	&dev_attr_ipato_enable.attr,
570 	&dev_attr_ipato_invert4.attr,
571 	&dev_attr_ipato_add4.attr,
572 	&dev_attr_ipato_del4.attr,
573 	&dev_attr_ipato_invert6.attr,
574 	&dev_attr_ipato_add6.attr,
575 	&dev_attr_ipato_del6.attr,
576 	NULL,
577 };
578 
579 static const struct attribute_group qeth_device_ipato_group = {
580 	.name = "ipa_takeover",
581 	.attrs = qeth_ipato_device_attrs,
582 };
583 
584 static ssize_t qeth_l3_dev_ip_add_show(struct device *dev, char *buf,
585 				       enum qeth_prot_versions proto,
586 				       enum qeth_ip_types type)
587 {
588 	struct qeth_card *card = dev_get_drvdata(dev);
589 	struct qeth_ipaddr *ipaddr;
590 	int str_len = 0;
591 	int i;
592 
593 	mutex_lock(&card->ip_lock);
594 	hash_for_each(card->ip_htable, i, ipaddr, hnode) {
595 		char addr_str[40];
596 		int entry_len;
597 
598 		if (ipaddr->proto != proto || ipaddr->type != type)
599 			continue;
600 
601 		entry_len = qeth_l3_ipaddr_to_string(proto, (u8 *)&ipaddr->u,
602 						     addr_str);
603 		if (entry_len < 0)
604 			continue;
605 
606 		/* Enough room to format %addr\n into null terminated page? */
607 		if (entry_len + 1 > PAGE_SIZE - str_len - 1)
608 			break;
609 
610 		entry_len = scnprintf(buf, PAGE_SIZE - str_len, "%s\n",
611 				      addr_str);
612 		str_len += entry_len;
613 		buf += entry_len;
614 	}
615 	mutex_unlock(&card->ip_lock);
616 
617 	return str_len ? str_len : scnprintf(buf, PAGE_SIZE, "\n");
618 }
619 
620 static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
621 					  struct device_attribute *attr,
622 					  char *buf)
623 {
624 	return qeth_l3_dev_ip_add_show(dev, buf, QETH_PROT_IPV4,
625 				       QETH_IP_TYPE_VIPA);
626 }
627 
628 static ssize_t qeth_l3_vipa_store(struct device *dev, const char *buf, bool add,
629 				  size_t count, enum qeth_prot_versions proto)
630 {
631 	struct qeth_card *card = dev_get_drvdata(dev);
632 	u8 addr[16] = {0, };
633 	int rc;
634 
635 	rc = qeth_l3_string_to_ipaddr(buf, proto, addr);
636 	if (!rc)
637 		rc = qeth_l3_modify_rxip_vipa(card, add, addr,
638 					      QETH_IP_TYPE_VIPA, proto);
639 	return rc ? rc : count;
640 }
641 
642 static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
643 		struct device_attribute *attr, const char *buf, size_t count)
644 {
645 	return qeth_l3_vipa_store(dev, buf, true, count, QETH_PROT_IPV4);
646 }
647 
648 static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
649 			qeth_l3_dev_vipa_add4_show,
650 			qeth_l3_dev_vipa_add4_store);
651 
652 static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
653 		struct device_attribute *attr, const char *buf, size_t count)
654 {
655 	return qeth_l3_vipa_store(dev, buf, true, count, QETH_PROT_IPV4);
656 }
657 
658 static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
659 			qeth_l3_dev_vipa_del4_store);
660 
661 static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
662 					  struct device_attribute *attr,
663 					  char *buf)
664 {
665 	return qeth_l3_dev_ip_add_show(dev, buf, QETH_PROT_IPV6,
666 				       QETH_IP_TYPE_VIPA);
667 }
668 
669 static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
670 		struct device_attribute *attr, const char *buf, size_t count)
671 {
672 	return qeth_l3_vipa_store(dev, buf, true, count, QETH_PROT_IPV6);
673 }
674 
675 static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
676 			qeth_l3_dev_vipa_add6_show,
677 			qeth_l3_dev_vipa_add6_store);
678 
679 static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
680 		struct device_attribute *attr, const char *buf, size_t count)
681 {
682 	return qeth_l3_vipa_store(dev, buf, false, count, QETH_PROT_IPV6);
683 }
684 
685 static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
686 			qeth_l3_dev_vipa_del6_store);
687 
688 static struct attribute *qeth_vipa_device_attrs[] = {
689 	&dev_attr_vipa_add4.attr,
690 	&dev_attr_vipa_del4.attr,
691 	&dev_attr_vipa_add6.attr,
692 	&dev_attr_vipa_del6.attr,
693 	NULL,
694 };
695 
696 static const struct attribute_group qeth_device_vipa_group = {
697 	.name = "vipa",
698 	.attrs = qeth_vipa_device_attrs,
699 };
700 
701 static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
702 					  struct device_attribute *attr,
703 					  char *buf)
704 {
705 	return qeth_l3_dev_ip_add_show(dev, buf, QETH_PROT_IPV4,
706 				       QETH_IP_TYPE_RXIP);
707 }
708 
709 static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
710 		 u8 *addr)
711 {
712 	__be32 ipv4_addr;
713 	struct in6_addr ipv6_addr;
714 
715 	if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
716 		return -EINVAL;
717 	}
718 	if (proto == QETH_PROT_IPV4) {
719 		memcpy(&ipv4_addr, addr, sizeof(ipv4_addr));
720 		if (ipv4_is_multicast(ipv4_addr)) {
721 			QETH_DBF_MESSAGE(2, "multicast rxip not supported.\n");
722 			return -EINVAL;
723 		}
724 	} else if (proto == QETH_PROT_IPV6) {
725 		memcpy(&ipv6_addr, addr, sizeof(ipv6_addr));
726 		if (ipv6_addr_is_multicast(&ipv6_addr)) {
727 			QETH_DBF_MESSAGE(2, "multicast rxip not supported.\n");
728 			return -EINVAL;
729 		}
730 	}
731 
732 	return 0;
733 }
734 
735 static ssize_t qeth_l3_rxip_store(struct device *dev, const char *buf, bool add,
736 				  size_t count, enum qeth_prot_versions proto)
737 {
738 	struct qeth_card *card = dev_get_drvdata(dev);
739 	u8 addr[16] = {0, };
740 	int rc;
741 
742 	rc = qeth_l3_parse_rxipe(buf, proto, addr);
743 	if (!rc)
744 		rc = qeth_l3_modify_rxip_vipa(card, add, addr,
745 					      QETH_IP_TYPE_RXIP, proto);
746 	return rc ? rc : count;
747 }
748 
749 static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
750 		struct device_attribute *attr, const char *buf, size_t count)
751 {
752 	return qeth_l3_rxip_store(dev, buf, true, count, QETH_PROT_IPV4);
753 }
754 
755 static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
756 			qeth_l3_dev_rxip_add4_show,
757 			qeth_l3_dev_rxip_add4_store);
758 
759 static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
760 		struct device_attribute *attr, const char *buf, size_t count)
761 {
762 	return qeth_l3_rxip_store(dev, buf, false, count, QETH_PROT_IPV4);
763 }
764 
765 static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
766 			qeth_l3_dev_rxip_del4_store);
767 
768 static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
769 					  struct device_attribute *attr,
770 					  char *buf)
771 {
772 	return qeth_l3_dev_ip_add_show(dev, buf, QETH_PROT_IPV6,
773 				       QETH_IP_TYPE_RXIP);
774 }
775 
776 static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
777 		struct device_attribute *attr, const char *buf, size_t count)
778 {
779 	return qeth_l3_rxip_store(dev, buf, true, count, QETH_PROT_IPV6);
780 }
781 
782 static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
783 			qeth_l3_dev_rxip_add6_show,
784 			qeth_l3_dev_rxip_add6_store);
785 
786 static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
787 		struct device_attribute *attr, const char *buf, size_t count)
788 {
789 	return qeth_l3_rxip_store(dev, buf, false, count, QETH_PROT_IPV6);
790 }
791 
792 static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
793 			qeth_l3_dev_rxip_del6_store);
794 
795 static struct attribute *qeth_rxip_device_attrs[] = {
796 	&dev_attr_rxip_add4.attr,
797 	&dev_attr_rxip_del4.attr,
798 	&dev_attr_rxip_add6.attr,
799 	&dev_attr_rxip_del6.attr,
800 	NULL,
801 };
802 
803 static const struct attribute_group qeth_device_rxip_group = {
804 	.name = "rxip",
805 	.attrs = qeth_rxip_device_attrs,
806 };
807 
808 static const struct attribute_group *qeth_l3_only_attr_groups[] = {
809 	&qeth_l3_device_attr_group,
810 	&qeth_device_ipato_group,
811 	&qeth_device_vipa_group,
812 	&qeth_device_rxip_group,
813 	NULL,
814 };
815 
816 int qeth_l3_create_device_attributes(struct device *dev)
817 {
818 	return sysfs_create_groups(&dev->kobj, qeth_l3_only_attr_groups);
819 }
820 
821 void qeth_l3_remove_device_attributes(struct device *dev)
822 {
823 	sysfs_remove_groups(&dev->kobj, qeth_l3_only_attr_groups);
824 }
825 
826 const struct attribute_group *qeth_l3_attr_groups[] = {
827 	&qeth_device_attr_group,
828 	&qeth_device_blkt_group,
829 	/* l3 specific, see qeth_l3_only_attr_groups: */
830 	&qeth_l3_device_attr_group,
831 	&qeth_device_ipato_group,
832 	&qeth_device_vipa_group,
833 	&qeth_device_rxip_group,
834 	NULL,
835 };
836