12 #include <linux/module.h>
14 #include <linux/icmp.h>
16 #include <linux/netfilter/x_tables.h>
20 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
23 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
25 #include <linux/netfilter_ipv6/ip6_tables.h>
43 return (addr32[0] & mask[0]) ^
44 (addr32[1] & mask[1]) ^
45 (addr32[2] & mask[2]) ^
46 (addr32[3] & mask[3]);
54 return *addr32 & *
mask;
56 return hmark_addr6_mask(addr32, mask);
61 static inline void hmark_swap_ports(
union hmark_ports *uports,
68 src =
ntohs(hp.b16.src);
69 dst =
ntohs(hp.b16.dst);
72 uports->
v32 = (dst << 16) | src;
74 uports->
v32 = (src << 16) | dst;
81 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
83 struct nf_conn *
ct = nf_ct_get(skb, &ctinfo);
87 if (ct ==
NULL || nf_ct_is_untracked(ct))
93 t->
src = hmark_addr_mask(otuple->
src.l3num, otuple->
src.u3.ip6,
95 t->
dst = hmark_addr_mask(otuple->
src.l3num, rtuple->
src.u3.ip6,
101 t->
proto = nf_ct_protonum(ct);
105 hmark_swap_ports(&t->
uports, info);
133 hmark_set_tuple_ports(
const struct sk_buff *skb,
unsigned int nhoff,
138 protoff = proto_ports_offset(t->
proto);
146 hmark_swap_ports(&t->
uports, info);
149 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
150 static int get_inner6_hdr(
const struct sk_buff *skb,
int *
offset)
154 icmp6h = skb_header_pointer(skb, *offset,
sizeof(_ih6), &_ih6);
171 unsigned int nhoff = 0;
175 ip6 = (
struct ipv6hdr *) (skb->
data + skb_network_offset(skb));
183 if (get_inner6_hdr(skb, &nhoff)) {
184 ip6 = skb_header_pointer(skb, nhoff,
sizeof(_ip6), &_ip6);
204 if (flag & IP6T_FH_F_FRAG)
207 hmark_set_tuple_ports(skb, nhoff, t, info);
220 if (hmark_ct_set_htuple(skb, &t, info) < 0)
223 if (hmark_pkt_set_htuple_ipv6(skb, &t, info) < 0)
227 skb->
mark = hmark_hash(&t, info);
232 static int get_inner_hdr(
const struct sk_buff *skb,
int iphsz,
int *nhoff)
238 icmph = skb_header_pointer(skb, *nhoff + iphsz,
sizeof(_ih), &_ih);
250 *nhoff += iphsz +
sizeof(_ih);
259 int nhoff = skb_network_offset(skb);
261 ip = (
struct iphdr *) (skb->
data + nhoff);
264 if (get_inner_hdr(skb, ip->ihl * 4, &nhoff)) {
265 ip = skb_header_pointer(skb, nhoff,
sizeof(_ip), &_ip);
287 hmark_set_tuple_ports(skb, (ip->ihl * 4) + nhoff, t, info);
301 if (hmark_ct_set_htuple(skb, &t, info) < 0)
304 if (hmark_pkt_set_htuple_ipv4(skb, &t, info) < 0)
308 skb->
mark = hmark_hash(&t, info);
317 pr_info(
"xt_HMARK: hash modulus can't be zero\n");
322 pr_info(
"xt_HMARK: proto mask must be zero with L3 mode\n");
328 pr_info(
"xt_HMARK: spi-mask and port-mask can't be combined\n");
334 pr_info(
"xt_HMARK: spi-set and port-set can't be combined\n");
344 .target = hmark_tg_v4,
346 .checkentry = hmark_tg_check,
349 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
353 .target = hmark_tg_v6,
355 .checkentry = hmark_tg_check,
361 static int __init hmark_tg_init(
void)
366 static void __exit hmark_tg_exit(
void)