| @@ -32,13 +32,13 @@ MODULE_ALIAS("ipt_HMARK"); · 31 unmodified lines |
| 32 | 32 | MODULE_ALIAS("ip6t_HMARK"); |
| 33 | 33 | |
| 34 | 34 | struct hmark_tuple { |
| 35 | | − u32 src; |
| 36 | | − u32 dst; |
| 35 | + __be32 src; |
| 36 | + __be32 dst; |
| 37 | 37 | union hmark_ports uports; |
| 38 | | − uint8_t proto; |
| 38 | + u8 proto; |
| 39 | 39 | }; |
| 40 | 40 | |
| 41 | | −static inline u32 hmark_addr6_mask(const __u32 *addr32, const __u32 *mask) |
| 41 | +static inline __be32 hmark_addr6_mask(const __be32 *addr32, const __be32 *mask) |
| 42 | 42 | { |
| 43 | 43 | return (addr32[0] & mask[0]) ^ |
| 44 | 44 | (addr32[1] & mask[1]) ^ |
| @@ -46,8 +46,8 @@ static inline u32 hmark_addr6_mask(const __u32 *addr32, const __u32 *mask) · 1 unmodified line |
| 46 | 46 | (addr32[3] & mask[3]); |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | | −static inline u32 |
| 50 | | −hmark_addr_mask(int l3num, const __u32 *addr32, const __u32 *mask) |
| 49 | +static inline __be32 |
| 50 | +hmark_addr_mask(int l3num, const __be32 *addr32, const __be32 *mask) |
| 51 | 51 | { |
| 52 | 52 | switch (l3num) { |
| 53 | 53 | case AF_INET: |
| @@ -58,6 +58,22 @@ hmark_addr_mask(int l3num, const __u32 *addr32, const __u32 *mask) · 4 unmodified lines |
| 58 | 58 | return 0; |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | +static inline void hmark_swap_ports(union hmark_ports *uports, |
| 62 | + const struct xt_hmark_info *info) |
| 63 | +{ |
| 64 | + union hmark_ports hp; |
| 65 | + u16 src, dst; |
| 66 | + |
| 67 | + hp.b32 = (uports->b32 & info->port_mask.b32) | info->port_set.b32; |
| 68 | + src = ntohs(hp.b16.src); |
| 69 | + dst = ntohs(hp.b16.dst); |
| 70 | + |
| 71 | + if (dst > src) |
| 72 | + uports->v32 = (dst << 16) | src; |
| 73 | + else |
| 74 | + uports->v32 = (src << 16) | dst; |
| 75 | +} |
| 76 | + |
| 61 | 77 | static int |
| 62 | 78 | hmark_ct_set_htuple(const struct sk_buff *skb, struct hmark_tuple *t, |
| 63 | 79 | const struct xt_hmark_info *info) |
| @@ -74,22 +90,19 @@ hmark_ct_set_htuple(const struct sk_buff *skb, struct hmark_tuple *t, · 10 unmodified lines |
| 74 | 90 | otuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; |
| 75 | 91 | rtuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; |
| 76 | 92 | |
| 77 | | − t->src = hmark_addr_mask(otuple->src.l3num, otuple->src.u3.all, |
| 78 | | − info->src_mask.all); |
| 79 | | − t->dst = hmark_addr_mask(otuple->src.l3num, rtuple->src.u3.all, |
| 80 | | − info->dst_mask.all); |
| 93 | + t->src = hmark_addr_mask(otuple->src.l3num, otuple->src.u3.ip6, |
| 94 | + info->src_mask.ip6); |
| 95 | + t->dst = hmark_addr_mask(otuple->src.l3num, rtuple->src.u3.ip6, |
| 96 | + info->dst_mask.ip6); |
| 81 | 97 | |
| 82 | 98 | if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) |
| 83 | 99 | return 0; |
| 84 | 100 | |
| 85 | 101 | t->proto = nf_ct_protonum(ct); |
| 86 | 102 | if (t->proto != IPPROTO_ICMP) { |
| 87 | | − t->uports.p16.src = otuple->src.u.all; |
| 88 | | − t->uports.p16.dst = rtuple->src.u.all; |
| 89 | | − t->uports.v32 = (t->uports.v32 & info->port_mask.v32) | |
| 90 | | − info->port_set.v32; |
| 91 | | − if (t->uports.p16.dst < t->uports.p16.src) |
| 92 | | − swap(t->uports.p16.dst, t->uports.p16.src); |
| 103 | + t->uports.b16.src = otuple->src.u.all; |
| 104 | + t->uports.b16.dst = rtuple->src.u.all; |
| 105 | + hmark_swap_ports(&t->uports, info); |
| 93 | 106 | } |
| 94 | 107 | |
| 95 | 108 | return 0; |
| @@ -98,15 +111,19 @@ hmark_ct_set_htuple(const struct sk_buff *skb, struct hmark_tuple *t, · 2 unmodified lines |
| 98 | 111 | #endif |
| 99 | 112 | } |
| 100 | 113 | |
| 114 | +/* This hash function is endian independent, to ensure consistent hashing if |
| 115 | + * the cluster is composed of big and little endian systems. */ |
| 101 | 116 | static inline u32 |
| 102 | 117 | hmark_hash(struct hmark_tuple *t, const struct xt_hmark_info *info) |
| 103 | 118 | { |
| 104 | 119 | u32 hash; |
| 120 | + u32 src = ntohl(t->src); |
| 121 | + u32 dst = ntohl(t->dst); |
| 105 | 122 | |
| 106 | | − if (t->dst < t->src) |
| 107 | | − swap(t->src, t->dst); |
| 123 | + if (dst < src) |
| 124 | + swap(src, dst); |
| 108 | 125 | |
| 109 | | − hash = jhash_3words(t->src, t->dst, t->uports.v32, info->hashrnd); |
| 126 | + hash = jhash_3words(src, dst, t->uports.v32, info->hashrnd); |
| 110 | 127 | hash = hash ^ (t->proto & info->proto_mask); |
| 111 | 128 | |
| 112 | 129 | return (((u64)hash * info->hmodulus) >> 32) + info->hoffset; |
| @@ -126,11 +143,7 @@ hmark_set_tuple_ports(const struct sk_buff *skb, unsigned int nhoff, · 13 unmodified lines |
| 126 | 143 | if (skb_copy_bits(skb, nhoff, &t->uports, sizeof(t->uports)) < 0) |
| 127 | 144 | return; |
| 128 | 145 | |
| 129 | | − t->uports.v32 = (t->uports.v32 & info->port_mask.v32) | |
| 130 | | − info->port_set.v32; |
| 131 | | − |
| 132 | | − if (t->uports.p16.dst < t->uports.p16.src) |
| 133 | | − swap(t->uports.p16.dst, t->uports.p16.src); |
| 146 | + hmark_swap_ports(&t->uports, info); |
| 134 | 147 | } |
| 135 | 148 | |
| 136 | 149 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) |
| @@ -178,8 +191,8 @@ hmark_pkt_set_htuple_ipv6(const struct sk_buff *skb, struct hmark_tuple *t, · 41 unmodified lines |
| 178 | 191 | return -1; |
| 179 | 192 | } |
| 180 | 193 | noicmp: |
| 181 | | − t->src = hmark_addr6_mask(ip6->saddr.s6_addr32, info->src_mask.all); |
| 182 | | − t->dst = hmark_addr6_mask(ip6->daddr.s6_addr32, info->dst_mask.all); |
| 194 | + t->src = hmark_addr6_mask(ip6->saddr.s6_addr32, info->src_mask.ip6); |
| 195 | + t->dst = hmark_addr6_mask(ip6->daddr.s6_addr32, info->dst_mask.ip6); |
| 183 | 196 | |
| 184 | 197 | if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) |
| 185 | 198 | return 0; |
| @@ -255,11 +268,8 @@ hmark_pkt_set_htuple_ipv4(const struct sk_buff *skb, struct hmark_tuple *t, · 69 unmodified lines |
| 255 | 268 | } |
| 256 | 269 | } |
| 257 | 270 | |
| 258 | | − t->src = (__force u32) ip->saddr; |
| 259 | | − t->dst = (__force u32) ip->daddr; |
| 260 | | − |
| 261 | | − t->src &= info->src_mask.ip; |
| 262 | | − t->dst &= info->dst_mask.ip; |
| 271 | + t->src = ip->saddr & info->src_mask.ip; |
| 272 | + t->dst = ip->daddr & info->dst_mask.ip; |
| 263 | 273 | |
| 264 | 274 | if (info->flags & XT_HMARK_FLAG(XT_HMARK_METHOD_L3)) |
| 265 | 275 | return 0; |