+static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
+{
+ struct ipt_addrtype_info_v1 *info = par->matchinfo;
+
+ if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
+ info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+ printk(KERN_ERR "ipt_addrtype: both incoming and outgoing "
+ "interface limitation cannot be selected\n");
+ return false;
+ }
+
+ if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
+ (1 << NF_INET_LOCAL_IN)) &&
+ info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+ printk(KERN_ERR "ipt_addrtype: output interface limitation "
+ "not valid in PRE_ROUTING and INPUT\n");
+ return false;
+ }
+
+ if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
+ (1 << NF_INET_LOCAL_OUT)) &&
+ info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+ printk(KERN_ERR "ipt_addrtype: input interface limitation "
+ "not valid in POST_ROUTING and OUTPUT\n");
+ return false;
+ }
+
+ return true;
+}
+
+static struct xt_match addrtype_mt_reg[] __read_mostly = {
+ {
+ .name = "addrtype",
+ .family = NFPROTO_IPV4,
+ .match = addrtype_mt_v0,
+ .matchsize = sizeof(struct ipt_addrtype_info),
+ .me = THIS_MODULE
+ },
+ {
+ .name = "addrtype",
+ .family = NFPROTO_IPV4,
+ .revision = 1,
+ .match = addrtype_mt_v1,
+ .checkentry = addrtype_mt_checkentry_v1,
+ .matchsize = sizeof(struct ipt_addrtype_info_v1),
+ .me = THIS_MODULE
+ }