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 #ifndef __QETH_L3_H__ 11 #define __QETH_L3_H__ 12 13 #include "qeth_core.h" 14 #include <linux/hashtable.h> 15 16 #define QETH_SNIFF_AVAIL 0x0008 17 18 enum qeth_ip_types { 19 QETH_IP_TYPE_NORMAL, 20 QETH_IP_TYPE_VIPA, 21 QETH_IP_TYPE_RXIP, 22 }; 23 24 struct qeth_ipaddr { 25 struct hlist_node hnode; 26 enum qeth_ip_types type; 27 unsigned char mac[ETH_ALEN]; 28 u8 is_multicast:1; 29 u8 in_progress:1; 30 u8 disp_flag:2; 31 u8 ipato:1; /* ucast only */ 32 33 /* is changed only for normal ip addresses 34 * for non-normal addresses it always is 1 35 */ 36 int ref_counter; 37 enum qeth_prot_versions proto; 38 union { 39 struct { 40 unsigned int addr; 41 unsigned int mask; 42 } a4; 43 struct { 44 struct in6_addr addr; 45 unsigned int pfxlen; 46 } a6; 47 } u; 48 }; 49 50 static inline void qeth_l3_init_ipaddr(struct qeth_ipaddr *addr, 51 enum qeth_ip_types type, 52 enum qeth_prot_versions proto) 53 { 54 memset(addr, 0, sizeof(*addr)); 55 addr->type = type; 56 addr->proto = proto; 57 addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING; 58 } 59 60 static inline bool qeth_l3_addr_match_ip(struct qeth_ipaddr *a1, 61 struct qeth_ipaddr *a2) 62 { 63 if (a1->proto != a2->proto) 64 return false; 65 if (a1->proto == QETH_PROT_IPV6) 66 return ipv6_addr_equal(&a1->u.a6.addr, &a2->u.a6.addr); 67 return a1->u.a4.addr == a2->u.a4.addr; 68 } 69 70 static inline bool qeth_l3_addr_match_all(struct qeth_ipaddr *a1, 71 struct qeth_ipaddr *a2) 72 { 73 /* Assumes that the pair was obtained via qeth_l3_addr_find_by_ip(), 74 * so 'proto' and 'addr' match for sure. 75 * 76 * For ucast: 77 * - 'mac' is always 0. 78 * - 'mask'/'pfxlen' for RXIP/VIPA is always 0. For NORMAL, matching 79 * values are required to avoid mixups in takeover eligibility. 80 * 81 * For mcast, 82 * - 'mac' is mapped from the IP, and thus always matches. 83 * - 'mask'/'pfxlen' is always 0. 84 */ 85 if (a1->type != a2->type) 86 return false; 87 if (a1->proto == QETH_PROT_IPV6) 88 return a1->u.a6.pfxlen == a2->u.a6.pfxlen; 89 return a1->u.a4.mask == a2->u.a4.mask; 90 } 91 92 static inline u64 qeth_l3_ipaddr_hash(struct qeth_ipaddr *addr) 93 { 94 u64 ret = 0; 95 u8 *point; 96 97 if (addr->proto == QETH_PROT_IPV6) { 98 point = (u8 *) &addr->u.a6.addr; 99 ret = get_unaligned((u64 *)point) ^ 100 get_unaligned((u64 *) (point + 8)); 101 } 102 if (addr->proto == QETH_PROT_IPV4) { 103 point = (u8 *) &addr->u.a4.addr; 104 ret = get_unaligned((u32 *) point); 105 } 106 return ret; 107 } 108 109 struct qeth_ipato_entry { 110 struct list_head entry; 111 enum qeth_prot_versions proto; 112 char addr[16]; 113 int mask_bits; 114 }; 115 116 extern const struct attribute_group *qeth_l3_attr_groups[]; 117 118 void qeth_l3_ipaddr_to_string(enum qeth_prot_versions, const __u8 *, char *); 119 int qeth_l3_create_device_attributes(struct device *); 120 void qeth_l3_remove_device_attributes(struct device *); 121 int qeth_l3_setrouting_v4(struct qeth_card *); 122 int qeth_l3_setrouting_v6(struct qeth_card *); 123 int qeth_l3_add_ipato_entry(struct qeth_card *, struct qeth_ipato_entry *); 124 int qeth_l3_del_ipato_entry(struct qeth_card *card, 125 enum qeth_prot_versions proto, u8 *addr, 126 int mask_bits); 127 void qeth_l3_update_ipato(struct qeth_card *card); 128 int qeth_l3_modify_hsuid(struct qeth_card *card, bool add); 129 int qeth_l3_modify_rxip_vipa(struct qeth_card *card, bool add, const u8 *ip, 130 enum qeth_ip_types type, 131 enum qeth_prot_versions proto); 132 133 #endif /* __QETH_L3_H__ */ 134