X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=net%2Fnetfilter%2Fxt_CONNMARK.c;h=c01524f817f04caa8a42aa5ec16dc7130fed6baf;hb=0f9005a6f7a82f4aacbd72f7b92322a8ca1c3f97;hp=22506e376be5b1a17a904720c391805eba6d6163;hpb=59af70385fb125f819d953801b6c45629836e916;p=powerpc.git diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c index 22506e376b..c01524f817 100644 --- a/net/netfilter/xt_CONNMARK.c +++ b/net/netfilter/xt_CONNMARK.c @@ -37,8 +37,8 @@ target(struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, unsigned int hooknum, - const void *targinfo, - void *userinfo) + const struct xt_target *target, + const void *targinfo) { const struct xt_connmark_target_info *markinfo = targinfo; u_int32_t diff; @@ -48,24 +48,37 @@ target(struct sk_buff **pskb, u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo); if (ctmark) { - switch(markinfo->mode) { - case XT_CONNMARK_SET: - newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; - if (newmark != *ctmark) - *ctmark = newmark; - break; - case XT_CONNMARK_SAVE: - newmark = (*ctmark & ~markinfo->mask) | ((*pskb)->nfmark & markinfo->mask); - if (*ctmark != newmark) - *ctmark = newmark; - break; - case XT_CONNMARK_RESTORE: - nfmark = (*pskb)->nfmark; - diff = (*ctmark ^ nfmark) & markinfo->mask; - if (diff != 0) - (*pskb)->nfmark = nfmark ^ diff; - break; - } + switch(markinfo->mode) { + case XT_CONNMARK_SET: + newmark = (*ctmark & ~markinfo->mask) | markinfo->mark; + if (newmark != *ctmark) { + *ctmark = newmark; +#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) + ip_conntrack_event_cache(IPCT_MARK, *pskb); +#else + nf_conntrack_event_cache(IPCT_MARK, *pskb); +#endif + } + break; + case XT_CONNMARK_SAVE: + newmark = (*ctmark & ~markinfo->mask) | + ((*pskb)->nfmark & markinfo->mask); + if (*ctmark != newmark) { + *ctmark = newmark; +#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) + ip_conntrack_event_cache(IPCT_MARK, *pskb); +#else + nf_conntrack_event_cache(IPCT_MARK, *pskb); +#endif + } + break; + case XT_CONNMARK_RESTORE: + nfmark = (*pskb)->nfmark; + diff = (*ctmark ^ nfmark) & markinfo->mask; + if (diff != 0) + (*pskb)->nfmark = nfmark ^ diff; + break; + } } return XT_CONTINUE; @@ -74,68 +87,94 @@ target(struct sk_buff **pskb, static int checkentry(const char *tablename, const void *entry, + const struct xt_target *target, void *targinfo, - unsigned int targinfosize, unsigned int hook_mask) { struct xt_connmark_target_info *matchinfo = targinfo; - if (targinfosize != XT_ALIGN(sizeof(struct xt_connmark_target_info))) { - printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", - targinfosize, - XT_ALIGN(sizeof(struct xt_connmark_target_info))); - return 0; - } if (matchinfo->mode == XT_CONNMARK_RESTORE) { - if (strcmp(tablename, "mangle") != 0) { - printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); - return 0; - } + if (strcmp(tablename, "mangle") != 0) { + printk(KERN_WARNING "CONNMARK: restore can only be " + "called from \"mangle\" table, not \"%s\"\n", + tablename); + return 0; + } } - if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) { printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); return 0; } - return 1; } -static struct xt_target connmark_reg = { - .name = "CONNMARK", - .target = &target, - .checkentry = &checkentry, - .me = THIS_MODULE -}; -static struct xt_target connmark6_reg = { - .name = "CONNMARK", - .target = &target, - .checkentry = &checkentry, - .me = THIS_MODULE +#ifdef CONFIG_COMPAT +struct compat_xt_connmark_target_info { + compat_ulong_t mark, mask; + u_int8_t mode; + u_int8_t __pad1; + u_int16_t __pad2; }; -static int __init init(void) +static void compat_from_user(void *dst, void *src) { - int ret; - - need_conntrack(); - - ret = xt_register_target(AF_INET, &connmark_reg); - if (ret) - return ret; + struct compat_xt_connmark_target_info *cm = src; + struct xt_connmark_target_info m = { + .mark = cm->mark, + .mask = cm->mask, + .mode = cm->mode, + }; + memcpy(dst, &m, sizeof(m)); +} - ret = xt_register_target(AF_INET6, &connmark6_reg); - if (ret) - xt_unregister_target(AF_INET, &connmark_reg); +static int compat_to_user(void __user *dst, void *src) +{ + struct xt_connmark_target_info *m = src; + struct compat_xt_connmark_target_info cm = { + .mark = m->mark, + .mask = m->mask, + .mode = m->mode, + }; + return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0; +} +#endif /* CONFIG_COMPAT */ + +static struct xt_target xt_connmark_target[] = { + { + .name = "CONNMARK", + .family = AF_INET, + .checkentry = checkentry, + .target = target, + .targetsize = sizeof(struct xt_connmark_target_info), +#ifdef CONFIG_COMPAT + .compatsize = sizeof(struct compat_xt_connmark_target_info), + .compat_from_user = compat_from_user, + .compat_to_user = compat_to_user, +#endif + .me = THIS_MODULE + }, + { + .name = "CONNMARK", + .family = AF_INET6, + .checkentry = checkentry, + .target = target, + .targetsize = sizeof(struct xt_connmark_target_info), + .me = THIS_MODULE + }, +}; - return ret; +static int __init xt_connmark_init(void) +{ + need_conntrack(); + return xt_register_targets(xt_connmark_target, + ARRAY_SIZE(xt_connmark_target)); } -static void __exit fini(void) +static void __exit xt_connmark_fini(void) { - xt_unregister_target(AF_INET, &connmark_reg); - xt_unregister_target(AF_INET6, &connmark6_reg); + xt_unregister_targets(xt_connmark_target, + ARRAY_SIZE(xt_connmark_target)); } -module_init(init); -module_exit(fini); +module_init(xt_connmark_init); +module_exit(xt_connmark_fini);