ia64/linux-2.6.18-xen.hg

annotate net/netfilter/xt_dccp.c @ 871:9cbcc9008446

xen/x86: don't initialize cpu_data[]'s apicid field on generic code

Afaict, this is not only redundant with the intialization done in
drivers/xen/core/smpboot.c, but actually results - at least for
secondary CPUs - in the Xen-specific value written to be later
overwritten with whatever the generic code determines (with no
guarantee that the two values are identical).

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 14 10:09:15 2009 +0100 (2009-05-14)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * iptables module for DCCP protocol header matching
ian@0 3 *
ian@0 4 * (C) 2005 by Harald Welte <laforge@netfilter.org>
ian@0 5 *
ian@0 6 * This program is free software; you can redistribute it and/or modify
ian@0 7 * it under the terms of the GNU General Public License version 2 as
ian@0 8 * published by the Free Software Foundation.
ian@0 9 */
ian@0 10
ian@0 11 #include <linux/module.h>
ian@0 12 #include <linux/skbuff.h>
ian@0 13 #include <linux/spinlock.h>
ian@0 14 #include <net/ip.h>
ian@0 15 #include <linux/dccp.h>
ian@0 16
ian@0 17 #include <linux/netfilter/x_tables.h>
ian@0 18 #include <linux/netfilter/xt_dccp.h>
ian@0 19
ian@0 20 #include <linux/netfilter_ipv4/ip_tables.h>
ian@0 21 #include <linux/netfilter_ipv6/ip6_tables.h>
ian@0 22
ian@0 23 MODULE_LICENSE("GPL");
ian@0 24 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
ian@0 25 MODULE_DESCRIPTION("Match for DCCP protocol packets");
ian@0 26 MODULE_ALIAS("ipt_dccp");
ian@0 27
ian@0 28 #define DCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
ian@0 29 || (!!((invflag) & (option)) ^ (cond)))
ian@0 30
ian@0 31 static unsigned char *dccp_optbuf;
ian@0 32 static DEFINE_SPINLOCK(dccp_buflock);
ian@0 33
ian@0 34 static inline int
ian@0 35 dccp_find_option(u_int8_t option,
ian@0 36 const struct sk_buff *skb,
ian@0 37 unsigned int protoff,
ian@0 38 const struct dccp_hdr *dh,
ian@0 39 int *hotdrop)
ian@0 40 {
ian@0 41 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
ian@0 42 unsigned char *op;
ian@0 43 unsigned int optoff = __dccp_hdr_len(dh);
ian@0 44 unsigned int optlen = dh->dccph_doff*4 - __dccp_hdr_len(dh);
ian@0 45 unsigned int i;
ian@0 46
ian@0 47 if (dh->dccph_doff * 4 < __dccp_hdr_len(dh)) {
ian@0 48 *hotdrop = 1;
ian@0 49 return 0;
ian@0 50 }
ian@0 51
ian@0 52 if (!optlen)
ian@0 53 return 0;
ian@0 54
ian@0 55 spin_lock_bh(&dccp_buflock);
ian@0 56 op = skb_header_pointer(skb, protoff + optoff, optlen, dccp_optbuf);
ian@0 57 if (op == NULL) {
ian@0 58 /* If we don't have the whole header, drop packet. */
ian@0 59 spin_unlock_bh(&dccp_buflock);
ian@0 60 *hotdrop = 1;
ian@0 61 return 0;
ian@0 62 }
ian@0 63
ian@0 64 for (i = 0; i < optlen; ) {
ian@0 65 if (op[i] == option) {
ian@0 66 spin_unlock_bh(&dccp_buflock);
ian@0 67 return 1;
ian@0 68 }
ian@0 69
ian@0 70 if (op[i] < 2)
ian@0 71 i++;
ian@0 72 else
ian@0 73 i += op[i+1]?:1;
ian@0 74 }
ian@0 75
ian@0 76 spin_unlock_bh(&dccp_buflock);
ian@0 77 return 0;
ian@0 78 }
ian@0 79
ian@0 80
ian@0 81 static inline int
ian@0 82 match_types(const struct dccp_hdr *dh, u_int16_t typemask)
ian@0 83 {
ian@0 84 return (typemask & (1 << dh->dccph_type));
ian@0 85 }
ian@0 86
ian@0 87 static inline int
ian@0 88 match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff,
ian@0 89 const struct dccp_hdr *dh, int *hotdrop)
ian@0 90 {
ian@0 91 return dccp_find_option(option, skb, protoff, dh, hotdrop);
ian@0 92 }
ian@0 93
ian@0 94 static int
ian@0 95 match(const struct sk_buff *skb,
ian@0 96 const struct net_device *in,
ian@0 97 const struct net_device *out,
ian@0 98 const struct xt_match *match,
ian@0 99 const void *matchinfo,
ian@0 100 int offset,
ian@0 101 unsigned int protoff,
ian@0 102 int *hotdrop)
ian@0 103 {
ian@0 104 const struct xt_dccp_info *info = matchinfo;
ian@0 105 struct dccp_hdr _dh, *dh;
ian@0 106
ian@0 107 if (offset)
ian@0 108 return 0;
ian@0 109
ian@0 110 dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh);
ian@0 111 if (dh == NULL) {
ian@0 112 *hotdrop = 1;
ian@0 113 return 0;
ian@0 114 }
ian@0 115
ian@0 116 return DCCHECK(((ntohs(dh->dccph_sport) >= info->spts[0])
ian@0 117 && (ntohs(dh->dccph_sport) <= info->spts[1])),
ian@0 118 XT_DCCP_SRC_PORTS, info->flags, info->invflags)
ian@0 119 && DCCHECK(((ntohs(dh->dccph_dport) >= info->dpts[0])
ian@0 120 && (ntohs(dh->dccph_dport) <= info->dpts[1])),
ian@0 121 XT_DCCP_DEST_PORTS, info->flags, info->invflags)
ian@0 122 && DCCHECK(match_types(dh, info->typemask),
ian@0 123 XT_DCCP_TYPE, info->flags, info->invflags)
ian@0 124 && DCCHECK(match_option(info->option, skb, protoff, dh,
ian@0 125 hotdrop),
ian@0 126 XT_DCCP_OPTION, info->flags, info->invflags);
ian@0 127 }
ian@0 128
ian@0 129 static int
ian@0 130 checkentry(const char *tablename,
ian@0 131 const void *inf,
ian@0 132 const struct xt_match *match,
ian@0 133 void *matchinfo,
ian@0 134 unsigned int matchsize,
ian@0 135 unsigned int hook_mask)
ian@0 136 {
ian@0 137 const struct xt_dccp_info *info = matchinfo;
ian@0 138
ian@0 139 return !(info->flags & ~XT_DCCP_VALID_FLAGS)
ian@0 140 && !(info->invflags & ~XT_DCCP_VALID_FLAGS)
ian@0 141 && !(info->invflags & ~info->flags);
ian@0 142 }
ian@0 143
ian@0 144 static struct xt_match dccp_match =
ian@0 145 {
ian@0 146 .name = "dccp",
ian@0 147 .match = match,
ian@0 148 .matchsize = sizeof(struct xt_dccp_info),
ian@0 149 .proto = IPPROTO_DCCP,
ian@0 150 .checkentry = checkentry,
ian@0 151 .family = AF_INET,
ian@0 152 .me = THIS_MODULE,
ian@0 153 };
ian@0 154 static struct xt_match dccp6_match =
ian@0 155 {
ian@0 156 .name = "dccp",
ian@0 157 .match = match,
ian@0 158 .matchsize = sizeof(struct xt_dccp_info),
ian@0 159 .proto = IPPROTO_DCCP,
ian@0 160 .checkentry = checkentry,
ian@0 161 .family = AF_INET6,
ian@0 162 .me = THIS_MODULE,
ian@0 163 };
ian@0 164
ian@0 165
ian@0 166 static int __init xt_dccp_init(void)
ian@0 167 {
ian@0 168 int ret;
ian@0 169
ian@0 170 /* doff is 8 bits, so the maximum option size is (4*256). Don't put
ian@0 171 * this in BSS since DaveM is worried about locked TLB's for kernel
ian@0 172 * BSS. */
ian@0 173 dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL);
ian@0 174 if (!dccp_optbuf)
ian@0 175 return -ENOMEM;
ian@0 176 ret = xt_register_match(&dccp_match);
ian@0 177 if (ret)
ian@0 178 goto out_kfree;
ian@0 179 ret = xt_register_match(&dccp6_match);
ian@0 180 if (ret)
ian@0 181 goto out_unreg;
ian@0 182
ian@0 183 return ret;
ian@0 184
ian@0 185 out_unreg:
ian@0 186 xt_unregister_match(&dccp_match);
ian@0 187 out_kfree:
ian@0 188 kfree(dccp_optbuf);
ian@0 189
ian@0 190 return ret;
ian@0 191 }
ian@0 192
ian@0 193 static void __exit xt_dccp_fini(void)
ian@0 194 {
ian@0 195 xt_unregister_match(&dccp6_match);
ian@0 196 xt_unregister_match(&dccp_match);
ian@0 197 kfree(dccp_optbuf);
ian@0 198 }
ian@0 199
ian@0 200 module_init(xt_dccp_init);
ian@0 201 module_exit(xt_dccp_fini);