Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
[NET]: Fully fix the memory leaks in sys_accept().
[NETFILTER]: iptables 32bit compat layer
[NETFILTER]: {ip,nf}_conntrack_netlink: fix expectation notifier unregistration
[NETFILTER]: fix ifdef for connmark support in nf_conntrack_netlink
[NETFILTER]: x_tables: unify IPv4/IPv6 multiport match
[NETFILTER]: x_tables: unify IPv4/IPv6 esp match
[NET]: Fix dentry leak in sys_accept().
[IPSEC]: Kill unused decap state structure
[IPSEC]: Kill unused decap state argument
[NET]: com90xx kmalloc fix
[TG3]: Update driver version and reldate.
[TG3]: Revert "Speed up SRAM access"

+1748 -783
+2 -2
drivers/net/arcnet/com90xx.c
··· 125 125 if (!io && !irq && !shmem && !*device && com90xx_skip_probe) 126 126 return; 127 127 128 - shmems = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(unsigned long), 128 + shmems = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(unsigned long), 129 129 GFP_KERNEL); 130 130 if (!shmems) 131 131 return; 132 - iomem = kzalloc(((0x10000-0xa0000) / 0x800) * sizeof(void __iomem *), 132 + iomem = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(void __iomem *), 133 133 GFP_KERNEL); 134 134 if (!iomem) { 135 135 kfree(shmems);
+25 -32
drivers/net/tg3.c
··· 69 69 70 70 #define DRV_MODULE_NAME "tg3" 71 71 #define PFX DRV_MODULE_NAME ": " 72 - #define DRV_MODULE_VERSION "3.55" 73 - #define DRV_MODULE_RELDATE "Mar 27, 2006" 72 + #define DRV_MODULE_VERSION "3.56" 73 + #define DRV_MODULE_RELDATE "Apr 1, 2006" 74 74 75 75 #define TG3_DEF_MAC_MODE 0 76 76 #define TG3_DEF_RX_MODE 0 ··· 497 497 unsigned long flags; 498 498 499 499 spin_lock_irqsave(&tp->indirect_lock, flags); 500 - if (tp->write32 != tg3_write_indirect_reg32) { 501 - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); 502 - tw32_f(TG3PCI_MEM_WIN_DATA, val); 500 + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 501 + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 503 502 504 - /* Always leave this as zero. */ 505 - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); 506 - } else { 507 - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 508 - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 509 - 510 - /* Always leave this as zero. */ 511 - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 512 - } 503 + /* Always leave this as zero. */ 504 + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 513 505 spin_unlock_irqrestore(&tp->indirect_lock, flags); 506 + } 507 + 508 + static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) 509 + { 510 + /* If no workaround is needed, write to mem space directly */ 511 + if (tp->write32 != tg3_write_indirect_reg32) 512 + tw32(NIC_SRAM_WIN_BASE + off, val); 513 + else 514 + tg3_write_mem(tp, off, val); 514 515 } 515 516 516 517 static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) ··· 519 518 unsigned long flags; 520 519 521 520 spin_lock_irqsave(&tp->indirect_lock, flags); 522 - if (tp->write32 != tg3_write_indirect_reg32) { 523 - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); 524 - *val = tr32(TG3PCI_MEM_WIN_DATA); 521 + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 522 + pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 525 523 526 - /* Always leave this as zero. */ 527 - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); 528 - } else { 529 - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 530 - pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 531 - 532 - /* Always leave this as zero. */ 533 - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 534 - } 524 + /* Always leave this as zero. */ 525 + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 535 526 spin_unlock_irqrestore(&tp->indirect_lock, flags); 536 527 } 537 528 ··· 1367 1374 } 1368 1375 } 1369 1376 1370 - tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); 1371 - 1372 1377 /* Finally, set the new power state. */ 1373 1378 pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); 1374 1379 udelay(100); /* Delay after power state change */ 1380 + 1381 + tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); 1375 1382 1376 1383 return 0; 1377 1384 } ··· 6540 6547 if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { 6541 6548 u32 val; 6542 6549 6543 - tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, 6544 - FWCMD_NICDRV_ALIVE2); 6545 - tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); 6550 + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, 6551 + FWCMD_NICDRV_ALIVE2); 6552 + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); 6546 6553 /* 5 seconds timeout */ 6547 - tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); 6554 + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); 6548 6555 val = tr32(GRC_RX_CPU_EVENT); 6549 6556 val |= (1 << 14); 6550 6557 tw32(GRC_RX_CPU_EVENT, val);
+67
include/linux/netfilter/x_tables.h
··· 142 142 #define ASSERT_WRITE_LOCK(x) 143 143 #include <linux/netfilter_ipv4/listhelp.h> 144 144 145 + #ifdef CONFIG_COMPAT 146 + #define COMPAT_TO_USER 1 147 + #define COMPAT_FROM_USER -1 148 + #define COMPAT_CALC_SIZE 0 149 + #endif 150 + 145 151 struct xt_match 146 152 { 147 153 struct list_head list; ··· 180 174 /* Called when entry of this type deleted. */ 181 175 void (*destroy)(const struct xt_match *match, void *matchinfo, 182 176 unsigned int matchinfosize); 177 + 178 + /* Called when userspace align differs from kernel space one */ 179 + int (*compat)(void *match, void **dstptr, int *size, int convert); 183 180 184 181 /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 185 182 struct module *me; ··· 228 219 /* Called when entry of this type deleted. */ 229 220 void (*destroy)(const struct xt_target *target, void *targinfo, 230 221 unsigned int targinfosize); 222 + 223 + /* Called when userspace align differs from kernel space one */ 224 + int (*compat)(void *target, void **dstptr, int *size, int convert); 231 225 232 226 /* Set this to THIS_MODULE if you are a module, otherwise NULL */ 233 227 struct module *me; ··· 326 314 extern struct xt_table_info *xt_alloc_table_info(unsigned int size); 327 315 extern void xt_free_table_info(struct xt_table_info *info); 328 316 317 + #ifdef CONFIG_COMPAT 318 + #include <net/compat.h> 319 + 320 + struct compat_xt_entry_match 321 + { 322 + union { 323 + struct { 324 + u_int16_t match_size; 325 + char name[XT_FUNCTION_MAXNAMELEN - 1]; 326 + u_int8_t revision; 327 + } user; 328 + u_int16_t match_size; 329 + } u; 330 + unsigned char data[0]; 331 + }; 332 + 333 + struct compat_xt_entry_target 334 + { 335 + union { 336 + struct { 337 + u_int16_t target_size; 338 + char name[XT_FUNCTION_MAXNAMELEN - 1]; 339 + u_int8_t revision; 340 + } user; 341 + u_int16_t target_size; 342 + } u; 343 + unsigned char data[0]; 344 + }; 345 + 346 + /* FIXME: this works only on 32 bit tasks 347 + * need to change whole approach in order to calculate align as function of 348 + * current task alignment */ 349 + 350 + struct compat_xt_counters 351 + { 352 + u_int32_t cnt[4]; 353 + }; 354 + 355 + struct compat_xt_counters_info 356 + { 357 + char name[XT_TABLE_MAXNAMELEN]; 358 + compat_uint_t num_counters; 359 + struct compat_xt_counters counters[0]; 360 + }; 361 + 362 + #define COMPAT_XT_ALIGN(s) (((s) + (__alignof__(struct compat_xt_counters)-1)) \ 363 + & ~(__alignof__(struct compat_xt_counters)-1)) 364 + 365 + extern void xt_compat_lock(int af); 366 + extern void xt_compat_unlock(int af); 367 + extern int xt_compat_match(void *match, void **dstptr, int *size, int convert); 368 + extern int xt_compat_target(void *target, void **dstptr, int *size, 369 + int convert); 370 + 371 + #endif /* CONFIG_COMPAT */ 329 372 #endif /* __KERNEL__ */ 330 373 331 374 #endif /* _X_TABLES_H */
+14
include/linux/netfilter/xt_esp.h
··· 1 + #ifndef _XT_ESP_H 2 + #define _XT_ESP_H 3 + 4 + struct xt_esp 5 + { 6 + u_int32_t spis[2]; /* Security Parameter Index */ 7 + u_int8_t invflags; /* Inverse flags */ 8 + }; 9 + 10 + /* Values for "invflags" field in struct xt_esp. */ 11 + #define XT_ESP_INV_SPI 0x01 /* Invert the sense of spi. */ 12 + #define XT_ESP_INV_MASK 0x01 /* All possible flags. */ 13 + 14 + #endif /*_XT_ESP_H*/
+30
include/linux/netfilter/xt_multiport.h
··· 1 + #ifndef _XT_MULTIPORT_H 2 + #define _XT_MULTIPORT_H 3 + 4 + enum xt_multiport_flags 5 + { 6 + XT_MULTIPORT_SOURCE, 7 + XT_MULTIPORT_DESTINATION, 8 + XT_MULTIPORT_EITHER 9 + }; 10 + 11 + #define XT_MULTI_PORTS 15 12 + 13 + /* Must fit inside union xt_matchinfo: 16 bytes */ 14 + struct xt_multiport 15 + { 16 + u_int8_t flags; /* Type of comparison */ 17 + u_int8_t count; /* Number of ports */ 18 + u_int16_t ports[XT_MULTI_PORTS]; /* Ports */ 19 + }; 20 + 21 + struct xt_multiport_v1 22 + { 23 + u_int8_t flags; /* Type of comparison */ 24 + u_int8_t count; /* Number of ports */ 25 + u_int16_t ports[XT_MULTI_PORTS]; /* Ports */ 26 + u_int8_t pflags[XT_MULTI_PORTS]; /* Port flags */ 27 + u_int8_t invert; /* Invert flag */ 28 + }; 29 + 30 + #endif /*_XT_MULTIPORT_H*/
+18
include/linux/netfilter_ipv4/ip_tables.h
··· 316 316 void *userdata); 317 317 318 318 #define IPT_ALIGN(s) XT_ALIGN(s) 319 + 320 + #ifdef CONFIG_COMPAT 321 + #include <net/compat.h> 322 + 323 + struct compat_ipt_entry 324 + { 325 + struct ipt_ip ip; 326 + compat_uint_t nfcache; 327 + u_int16_t target_offset; 328 + u_int16_t next_offset; 329 + compat_uint_t comefrom; 330 + struct compat_xt_counters counters; 331 + unsigned char elems[0]; 332 + }; 333 + 334 + #define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s) 335 + 336 + #endif /* CONFIG_COMPAT */ 319 337 #endif /*__KERNEL__*/ 320 338 #endif /* _IPTABLES_H */
+4 -10
include/linux/netfilter_ipv4/ipt_esp.h
··· 1 1 #ifndef _IPT_ESP_H 2 2 #define _IPT_ESP_H 3 3 4 - struct ipt_esp 5 - { 6 - u_int32_t spis[2]; /* Security Parameter Index */ 7 - u_int8_t invflags; /* Inverse flags */ 8 - }; 4 + #include <linux/netfilter/xt_esp.h> 9 5 10 - 11 - 12 - /* Values for "invflags" field in struct ipt_esp. */ 13 - #define IPT_ESP_INV_SPI 0x01 /* Invert the sense of spi. */ 14 - #define IPT_ESP_INV_MASK 0x01 /* All possible flags. */ 6 + #define ipt_esp xt_esp 7 + #define IPT_ESP_INV_SPI XT_ESP_INV_SPI 8 + #define IPT_ESP_INV_MASK XT_ESP_INV_MASK 15 9 16 10 #endif /*_IPT_ESP_H*/
+8 -23
include/linux/netfilter_ipv4/ipt_multiport.h
··· 1 1 #ifndef _IPT_MULTIPORT_H 2 2 #define _IPT_MULTIPORT_H 3 - #include <linux/netfilter_ipv4/ip_tables.h> 4 3 5 - enum ipt_multiport_flags 6 - { 7 - IPT_MULTIPORT_SOURCE, 8 - IPT_MULTIPORT_DESTINATION, 9 - IPT_MULTIPORT_EITHER 10 - }; 4 + #include <linux/netfilter/xt_multiport.h> 11 5 12 - #define IPT_MULTI_PORTS 15 6 + #define IPT_MULTIPORT_SOURCE XT_MULTIPORT_SOURCE 7 + #define IPT_MULTIPORT_DESTINATION XT_MULTIPORT_DESTINATION 8 + #define IPT_MULTIPORT_EITHER XT_MULTIPORT_EITHER 13 9 14 - /* Must fit inside union ipt_matchinfo: 16 bytes */ 15 - struct ipt_multiport 16 - { 17 - u_int8_t flags; /* Type of comparison */ 18 - u_int8_t count; /* Number of ports */ 19 - u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */ 20 - }; 10 + #define IPT_MULTI_PORTS XT_MULTI_PORTS 21 11 22 - struct ipt_multiport_v1 23 - { 24 - u_int8_t flags; /* Type of comparison */ 25 - u_int8_t count; /* Number of ports */ 26 - u_int16_t ports[IPT_MULTI_PORTS]; /* Ports */ 27 - u_int8_t pflags[IPT_MULTI_PORTS]; /* Port flags */ 28 - u_int8_t invert; /* Invert flag */ 29 - }; 12 + #define ipt_multiport xt_multiport 13 + #define ipt_multiport_v1 xt_multiport_v1 14 + 30 15 #endif /*_IPT_MULTIPORT_H*/
+4 -8
include/linux/netfilter_ipv6/ip6t_esp.h
··· 1 1 #ifndef _IP6T_ESP_H 2 2 #define _IP6T_ESP_H 3 3 4 - struct ip6t_esp 5 - { 6 - u_int32_t spis[2]; /* Security Parameter Index */ 7 - u_int8_t invflags; /* Inverse flags */ 8 - }; 4 + #include <linux/netfilter/xt_esp.h> 9 5 10 - /* Values for "invflags" field in struct ip6t_esp. */ 11 - #define IP6T_ESP_INV_SPI 0x01 /* Invert the sense of spi. */ 12 - #define IP6T_ESP_INV_MASK 0x01 /* All possible flags. */ 6 + #define ip6t_esp xt_esp 7 + #define IP6T_ESP_INV_SPI XT_ESP_INV_SPI 8 + #define IP6T_ESP_INV_MASK XT_ESP_INV_MASK 13 9 14 10 #endif /*_IP6T_ESP_H*/
+9 -16
include/linux/netfilter_ipv6/ip6t_multiport.h
··· 1 1 #ifndef _IP6T_MULTIPORT_H 2 2 #define _IP6T_MULTIPORT_H 3 - #include <linux/netfilter_ipv6/ip6_tables.h> 4 3 5 - enum ip6t_multiport_flags 6 - { 7 - IP6T_MULTIPORT_SOURCE, 8 - IP6T_MULTIPORT_DESTINATION, 9 - IP6T_MULTIPORT_EITHER 10 - }; 4 + #include <linux/netfilter/xt_multiport.h> 11 5 12 - #define IP6T_MULTI_PORTS 15 6 + #define IP6T_MULTIPORT_SOURCE XT_MULTIPORT_SOURCE 7 + #define IP6T_MULTIPORT_DESTINATION XT_MULTIPORT_DESTINATION 8 + #define IP6T_MULTIPORT_EITHER XT_MULTIPORT_EITHER 13 9 14 - /* Must fit inside union ip6t_matchinfo: 16 bytes */ 15 - struct ip6t_multiport 16 - { 17 - u_int8_t flags; /* Type of comparison */ 18 - u_int8_t count; /* Number of ports */ 19 - u_int16_t ports[IP6T_MULTI_PORTS]; /* Ports */ 20 - }; 21 - #endif /*_IPT_MULTIPORT_H*/ 10 + #define IP6T_MULTI_PORTS XT_MULTI_PORTS 11 + 12 + #define ip6t_multiport xt_multiport 13 + 14 + #endif /*_IP6T_MULTIPORT_H*/
+2 -17
include/net/xfrm.h
··· 242 242 243 243 extern void xfrm_state_delete_tunnel(struct xfrm_state *x); 244 244 245 - struct xfrm_decap_state; 246 245 struct xfrm_type 247 246 { 248 247 char *description; ··· 250 251 251 252 int (*init_state)(struct xfrm_state *x); 252 253 void (*destructor)(struct xfrm_state *); 253 - int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); 254 + int (*input)(struct xfrm_state *, struct sk_buff *skb); 254 255 int (*output)(struct xfrm_state *, struct sk_buff *pskb); 255 256 /* Estimate maximal size of result of transformation of a dgram */ 256 257 u32 (*get_max_size)(struct xfrm_state *, int size); ··· 605 606 606 607 extern void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev); 607 608 608 - /* Decapsulation state, used by the input to store data during 609 - * decapsulation procedure, to be used later (during the policy 610 - * check 611 - */ 612 - struct xfrm_decap_state { 613 - char decap_data[20]; 614 - __u16 decap_type; 615 - }; 616 - 617 - struct sec_decap_state { 618 - struct xfrm_state *xvec; 619 - struct xfrm_decap_state decap; 620 - }; 621 - 622 609 struct sec_path 623 610 { 624 611 atomic_t refcnt; 625 612 int len; 626 - struct sec_decap_state x[XFRM_MAX_DEPTH]; 613 + struct xfrm_state *xvec[XFRM_MAX_DEPTH]; 627 614 }; 628 615 629 616 static inline struct sec_path *
+1 -2
net/compat.c
··· 476 476 int err; 477 477 struct socket *sock; 478 478 479 - /* SO_SET_REPLACE seems to be the same in all levels */ 480 - if (optname == IPT_SO_SET_REPLACE) 479 + if (level == SOL_IPV6 && optname == IPT_SO_SET_REPLACE) 481 480 return do_netfilter_replace(fd, level, optname, 482 481 optval, optlen); 483 482
+1 -1
net/ipv4/ah4.c
··· 116 116 return err; 117 117 } 118 118 119 - static int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) 119 + static int ah_input(struct xfrm_state *x, struct sk_buff *skb) 120 120 { 121 121 int ah_hlen; 122 122 struct iphdr *iph;
+1 -4
net/ipv4/esp4.c
··· 133 133 * expensive, so we only support truncated data, which is the recommended 134 134 * and common case. 135 135 */ 136 - static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) 136 + static int esp_input(struct xfrm_state *x, struct sk_buff *skb) 137 137 { 138 138 struct iphdr *iph; 139 139 struct ip_esp_hdr *esph; ··· 207 207 if (x->encap) { 208 208 struct xfrm_encap_tmpl *encap = x->encap; 209 209 struct udphdr *uh; 210 - 211 - if (encap->encap_type != decap->decap_type) 212 - goto out; 213 210 214 211 uh = (struct udphdr *)(iph + 1); 215 212 encap_len = (void*)esph - (void*)uh;
+1 -2
net/ipv4/ipcomp.c
··· 81 81 return err; 82 82 } 83 83 84 - static int ipcomp_input(struct xfrm_state *x, 85 - struct xfrm_decap_state *decap, struct sk_buff *skb) 84 + static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) 86 85 { 87 86 u8 nexthdr; 88 87 int err = 0;
+4 -14
net/ipv4/netfilter/Kconfig
··· 221 221 222 222 To compile it as a module, choose M here. If unsure, say N. 223 223 224 - config IP_NF_MATCH_MULTIPORT 225 - tristate "Multiple port match support" 226 - depends on IP_NF_IPTABLES 227 - help 228 - Multiport matching allows you to match TCP or UDP packets based on 229 - a series of source or destination ports: normally a rule can only 230 - match a single range of ports. 231 - 232 - To compile it as a module, choose M here. If unsure, say N. 233 - 234 224 config IP_NF_MATCH_TOS 235 225 tristate "TOS match support" 236 226 depends on IP_NF_IPTABLES ··· 262 272 263 273 To compile it as a module, choose M here. If unsure, say N. 264 274 265 - config IP_NF_MATCH_AH_ESP 266 - tristate "AH/ESP match support" 275 + config IP_NF_MATCH_AH 276 + tristate "AH match support" 267 277 depends on IP_NF_IPTABLES 268 278 help 269 - These two match extensions (`ah' and `esp') allow you to match a 270 - range of SPIs inside AH or ESP headers of IPSec packets. 279 + This match extension allows you to match a range of SPIs 280 + inside AH header of IPSec packets. 271 281 272 282 To compile it as a module, choose M here. If unsure, say N. 273 283
+1 -2
net/ipv4/netfilter/Makefile
··· 53 53 # matches 54 54 obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o 55 55 obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o 56 - obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o 57 56 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o 58 57 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o 59 58 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o 60 59 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o 61 60 obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o 62 - obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o 61 + obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o 63 62 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o 64 63 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 65 64
+1 -1
net/ipv4/netfilter/ip_conntrack_netlink.c
··· 1658 1658 printk("ctnetlink: unregistering from nfnetlink.\n"); 1659 1659 1660 1660 #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS 1661 - ip_conntrack_unregister_notifier(&ctnl_notifier_exp); 1661 + ip_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); 1662 1662 ip_conntrack_unregister_notifier(&ctnl_notifier); 1663 1663 #endif 1664 1664
+1016 -140
net/ipv4/netfilter/ip_tables.c
··· 24 24 #include <linux/module.h> 25 25 #include <linux/icmp.h> 26 26 #include <net/ip.h> 27 + #include <net/compat.h> 27 28 #include <asm/uaccess.h> 28 29 #include <linux/mutex.h> 29 30 #include <linux/proc_fs.h> ··· 800 799 } 801 800 } 802 801 803 - static int 804 - copy_entries_to_user(unsigned int total_size, 805 - struct ipt_table *table, 806 - void __user *userptr) 802 + static inline struct xt_counters * alloc_counters(struct ipt_table *table) 807 803 { 808 - unsigned int off, num, countersize; 809 - struct ipt_entry *e; 804 + unsigned int countersize; 810 805 struct xt_counters *counters; 811 806 struct xt_table_info *private = table->private; 812 - int ret = 0; 813 - void *loc_cpu_entry; 814 807 815 808 /* We need atomic snapshot of counters: rest doesn't change 816 809 (other than comefrom, which userspace doesn't care ··· 813 818 counters = vmalloc_node(countersize, numa_node_id()); 814 819 815 820 if (counters == NULL) 816 - return -ENOMEM; 821 + return ERR_PTR(-ENOMEM); 817 822 818 823 /* First, sum counters... */ 819 824 write_lock_bh(&table->lock); 820 825 get_counters(private, counters); 821 826 write_unlock_bh(&table->lock); 827 + 828 + return counters; 829 + } 830 + 831 + static int 832 + copy_entries_to_user(unsigned int total_size, 833 + struct ipt_table *table, 834 + void __user *userptr) 835 + { 836 + unsigned int off, num; 837 + struct ipt_entry *e; 838 + struct xt_counters *counters; 839 + struct xt_table_info *private = table->private; 840 + int ret = 0; 841 + void *loc_cpu_entry; 842 + 843 + counters = alloc_counters(table); 844 + if (IS_ERR(counters)) 845 + return PTR_ERR(counters); 822 846 823 847 /* choose the copy that is on our node/cpu, ... 824 848 * This choice is lazy (because current thread is ··· 898 884 return ret; 899 885 } 900 886 887 + #ifdef CONFIG_COMPAT 888 + struct compat_delta { 889 + struct compat_delta *next; 890 + u_int16_t offset; 891 + short delta; 892 + }; 893 + 894 + static struct compat_delta *compat_offsets = NULL; 895 + 896 + static int compat_add_offset(u_int16_t offset, short delta) 897 + { 898 + struct compat_delta *tmp; 899 + 900 + tmp = kmalloc(sizeof(struct compat_delta), GFP_KERNEL); 901 + if (!tmp) 902 + return -ENOMEM; 903 + tmp->offset = offset; 904 + tmp->delta = delta; 905 + if (compat_offsets) { 906 + tmp->next = compat_offsets->next; 907 + compat_offsets->next = tmp; 908 + } else { 909 + compat_offsets = tmp; 910 + tmp->next = NULL; 911 + } 912 + return 0; 913 + } 914 + 915 + static void compat_flush_offsets(void) 916 + { 917 + struct compat_delta *tmp, *next; 918 + 919 + if (compat_offsets) { 920 + for(tmp = compat_offsets; tmp; tmp = next) { 921 + next = tmp->next; 922 + kfree(tmp); 923 + } 924 + compat_offsets = NULL; 925 + } 926 + } 927 + 928 + static short compat_calc_jump(u_int16_t offset) 929 + { 930 + struct compat_delta *tmp; 931 + short delta; 932 + 933 + for(tmp = compat_offsets, delta = 0; tmp; tmp = tmp->next) 934 + if (tmp->offset < offset) 935 + delta += tmp->delta; 936 + return delta; 937 + } 938 + 939 + struct compat_ipt_standard_target 940 + { 941 + struct compat_xt_entry_target target; 942 + compat_int_t verdict; 943 + }; 944 + 945 + #define IPT_ST_OFFSET (sizeof(struct ipt_standard_target) - \ 946 + sizeof(struct compat_ipt_standard_target)) 947 + 948 + struct compat_ipt_standard 949 + { 950 + struct compat_ipt_entry entry; 951 + struct compat_ipt_standard_target target; 952 + }; 953 + 954 + static int compat_ipt_standard_fn(void *target, 955 + void **dstptr, int *size, int convert) 956 + { 957 + struct compat_ipt_standard_target compat_st, *pcompat_st; 958 + struct ipt_standard_target st, *pst; 959 + int ret; 960 + 961 + ret = 0; 962 + switch (convert) { 963 + case COMPAT_TO_USER: 964 + pst = (struct ipt_standard_target *)target; 965 + memcpy(&compat_st.target, &pst->target, 966 + sizeof(struct ipt_entry_target)); 967 + compat_st.verdict = pst->verdict; 968 + if (compat_st.verdict > 0) 969 + compat_st.verdict -= 970 + compat_calc_jump(compat_st.verdict); 971 + compat_st.target.u.user.target_size = 972 + sizeof(struct compat_ipt_standard_target); 973 + if (__copy_to_user(*dstptr, &compat_st, 974 + sizeof(struct compat_ipt_standard_target))) 975 + ret = -EFAULT; 976 + *size -= IPT_ST_OFFSET; 977 + *dstptr += sizeof(struct compat_ipt_standard_target); 978 + break; 979 + case COMPAT_FROM_USER: 980 + pcompat_st = 981 + (struct compat_ipt_standard_target *)target; 982 + memcpy(&st.target, &pcompat_st->target, 983 + sizeof(struct ipt_entry_target)); 984 + st.verdict = pcompat_st->verdict; 985 + if (st.verdict > 0) 986 + st.verdict += compat_calc_jump(st.verdict); 987 + st.target.u.user.target_size = 988 + sizeof(struct ipt_standard_target); 989 + memcpy(*dstptr, &st, 990 + sizeof(struct ipt_standard_target)); 991 + *size += IPT_ST_OFFSET; 992 + *dstptr += sizeof(struct ipt_standard_target); 993 + break; 994 + case COMPAT_CALC_SIZE: 995 + *size += IPT_ST_OFFSET; 996 + break; 997 + default: 998 + ret = -ENOPROTOOPT; 999 + break; 1000 + } 1001 + return ret; 1002 + } 1003 + 1004 + static inline int 1005 + compat_calc_match(struct ipt_entry_match *m, int * size) 1006 + { 1007 + if (m->u.kernel.match->compat) 1008 + m->u.kernel.match->compat(m, NULL, size, COMPAT_CALC_SIZE); 1009 + else 1010 + xt_compat_match(m, NULL, size, COMPAT_CALC_SIZE); 1011 + return 0; 1012 + } 1013 + 1014 + static int compat_calc_entry(struct ipt_entry *e, struct xt_table_info *info, 1015 + void *base, struct xt_table_info *newinfo) 1016 + { 1017 + struct ipt_entry_target *t; 1018 + u_int16_t entry_offset; 1019 + int off, i, ret; 1020 + 1021 + off = 0; 1022 + entry_offset = (void *)e - base; 1023 + IPT_MATCH_ITERATE(e, compat_calc_match, &off); 1024 + t = ipt_get_target(e); 1025 + if (t->u.kernel.target->compat) 1026 + t->u.kernel.target->compat(t, NULL, &off, COMPAT_CALC_SIZE); 1027 + else 1028 + xt_compat_target(t, NULL, &off, COMPAT_CALC_SIZE); 1029 + newinfo->size -= off; 1030 + ret = compat_add_offset(entry_offset, off); 1031 + if (ret) 1032 + return ret; 1033 + 1034 + for (i = 0; i< NF_IP_NUMHOOKS; i++) { 1035 + if (info->hook_entry[i] && (e < (struct ipt_entry *) 1036 + (base + info->hook_entry[i]))) 1037 + newinfo->hook_entry[i] -= off; 1038 + if (info->underflow[i] && (e < (struct ipt_entry *) 1039 + (base + info->underflow[i]))) 1040 + newinfo->underflow[i] -= off; 1041 + } 1042 + return 0; 1043 + } 1044 + 1045 + static int compat_table_info(struct xt_table_info *info, 1046 + struct xt_table_info *newinfo) 1047 + { 1048 + void *loc_cpu_entry; 1049 + int i; 1050 + 1051 + if (!newinfo || !info) 1052 + return -EINVAL; 1053 + 1054 + memset(newinfo, 0, sizeof(struct xt_table_info)); 1055 + newinfo->size = info->size; 1056 + newinfo->number = info->number; 1057 + for (i = 0; i < NF_IP_NUMHOOKS; i++) { 1058 + newinfo->hook_entry[i] = info->hook_entry[i]; 1059 + newinfo->underflow[i] = info->underflow[i]; 1060 + } 1061 + loc_cpu_entry = info->entries[raw_smp_processor_id()]; 1062 + return IPT_ENTRY_ITERATE(loc_cpu_entry, info->size, 1063 + compat_calc_entry, info, loc_cpu_entry, newinfo); 1064 + } 1065 + #endif 1066 + 1067 + static int get_info(void __user *user, int *len, int compat) 1068 + { 1069 + char name[IPT_TABLE_MAXNAMELEN]; 1070 + struct ipt_table *t; 1071 + int ret; 1072 + 1073 + if (*len != sizeof(struct ipt_getinfo)) { 1074 + duprintf("length %u != %u\n", *len, 1075 + (unsigned int)sizeof(struct ipt_getinfo)); 1076 + return -EINVAL; 1077 + } 1078 + 1079 + if (copy_from_user(name, user, sizeof(name)) != 0) 1080 + return -EFAULT; 1081 + 1082 + name[IPT_TABLE_MAXNAMELEN-1] = '\0'; 1083 + #ifdef CONFIG_COMPAT 1084 + if (compat) 1085 + xt_compat_lock(AF_INET); 1086 + #endif 1087 + t = try_then_request_module(xt_find_table_lock(AF_INET, name), 1088 + "iptable_%s", name); 1089 + if (t && !IS_ERR(t)) { 1090 + struct ipt_getinfo info; 1091 + struct xt_table_info *private = t->private; 1092 + 1093 + #ifdef CONFIG_COMPAT 1094 + if (compat) { 1095 + struct xt_table_info tmp; 1096 + ret = compat_table_info(private, &tmp); 1097 + compat_flush_offsets(); 1098 + private = &tmp; 1099 + } 1100 + #endif 1101 + info.valid_hooks = t->valid_hooks; 1102 + memcpy(info.hook_entry, private->hook_entry, 1103 + sizeof(info.hook_entry)); 1104 + memcpy(info.underflow, private->underflow, 1105 + sizeof(info.underflow)); 1106 + info.num_entries = private->number; 1107 + info.size = private->size; 1108 + strcpy(info.name, name); 1109 + 1110 + if (copy_to_user(user, &info, *len) != 0) 1111 + ret = -EFAULT; 1112 + else 1113 + ret = 0; 1114 + 1115 + xt_table_unlock(t); 1116 + module_put(t->me); 1117 + } else 1118 + ret = t ? PTR_ERR(t) : -ENOENT; 1119 + #ifdef CONFIG_COMPAT 1120 + if (compat) 1121 + xt_compat_unlock(AF_INET); 1122 + #endif 1123 + return ret; 1124 + } 1125 + 901 1126 static int 902 - get_entries(const struct ipt_get_entries *entries, 903 - struct ipt_get_entries __user *uptr) 1127 + get_entries(struct ipt_get_entries __user *uptr, int *len) 904 1128 { 905 1129 int ret; 1130 + struct ipt_get_entries get; 906 1131 struct ipt_table *t; 907 1132 908 - t = xt_find_table_lock(AF_INET, entries->name); 1133 + if (*len < sizeof(get)) { 1134 + duprintf("get_entries: %u < %d\n", *len, 1135 + (unsigned int)sizeof(get)); 1136 + return -EINVAL; 1137 + } 1138 + if (copy_from_user(&get, uptr, sizeof(get)) != 0) 1139 + return -EFAULT; 1140 + if (*len != sizeof(struct ipt_get_entries) + get.size) { 1141 + duprintf("get_entries: %u != %u\n", *len, 1142 + (unsigned int)(sizeof(struct ipt_get_entries) + 1143 + get.size)); 1144 + return -EINVAL; 1145 + } 1146 + 1147 + t = xt_find_table_lock(AF_INET, get.name); 909 1148 if (t && !IS_ERR(t)) { 910 1149 struct xt_table_info *private = t->private; 911 1150 duprintf("t->private->number = %u\n", 912 1151 private->number); 913 - if (entries->size == private->size) 1152 + if (get.size == private->size) 914 1153 ret = copy_entries_to_user(private->size, 915 1154 t, uptr->entrytable); 916 1155 else { 917 1156 duprintf("get_entries: I've got %u not %u!\n", 918 1157 private->size, 919 - entries->size); 1158 + get.size); 920 1159 ret = -EINVAL; 921 1160 } 922 1161 module_put(t->me); ··· 1181 914 } 1182 915 1183 916 static int 917 + __do_replace(const char *name, unsigned int valid_hooks, 918 + struct xt_table_info *newinfo, unsigned int num_counters, 919 + void __user *counters_ptr) 920 + { 921 + int ret; 922 + struct ipt_table *t; 923 + struct xt_table_info *oldinfo; 924 + struct xt_counters *counters; 925 + void *loc_cpu_old_entry; 926 + 927 + ret = 0; 928 + counters = vmalloc(num_counters * sizeof(struct xt_counters)); 929 + if (!counters) { 930 + ret = -ENOMEM; 931 + goto out; 932 + } 933 + 934 + t = try_then_request_module(xt_find_table_lock(AF_INET, name), 935 + "iptable_%s", name); 936 + if (!t || IS_ERR(t)) { 937 + ret = t ? PTR_ERR(t) : -ENOENT; 938 + goto free_newinfo_counters_untrans; 939 + } 940 + 941 + /* You lied! */ 942 + if (valid_hooks != t->valid_hooks) { 943 + duprintf("Valid hook crap: %08X vs %08X\n", 944 + valid_hooks, t->valid_hooks); 945 + ret = -EINVAL; 946 + goto put_module; 947 + } 948 + 949 + oldinfo = xt_replace_table(t, num_counters, newinfo, &ret); 950 + if (!oldinfo) 951 + goto put_module; 952 + 953 + /* Update module usage count based on number of rules */ 954 + duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n", 955 + oldinfo->number, oldinfo->initial_entries, newinfo->number); 956 + if ((oldinfo->number > oldinfo->initial_entries) || 957 + (newinfo->number <= oldinfo->initial_entries)) 958 + module_put(t->me); 959 + if ((oldinfo->number > oldinfo->initial_entries) && 960 + (newinfo->number <= oldinfo->initial_entries)) 961 + module_put(t->me); 962 + 963 + /* Get the old counters. */ 964 + get_counters(oldinfo, counters); 965 + /* Decrease module usage counts and free resource */ 966 + loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 967 + IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 968 + xt_free_table_info(oldinfo); 969 + if (copy_to_user(counters_ptr, counters, 970 + sizeof(struct xt_counters) * num_counters) != 0) 971 + ret = -EFAULT; 972 + vfree(counters); 973 + xt_table_unlock(t); 974 + return ret; 975 + 976 + put_module: 977 + module_put(t->me); 978 + xt_table_unlock(t); 979 + free_newinfo_counters_untrans: 980 + vfree(counters); 981 + out: 982 + return ret; 983 + } 984 + 985 + static int 1184 986 do_replace(void __user *user, unsigned int len) 1185 987 { 1186 988 int ret; 1187 989 struct ipt_replace tmp; 1188 - struct ipt_table *t; 1189 - struct xt_table_info *newinfo, *oldinfo; 1190 - struct xt_counters *counters; 1191 - void *loc_cpu_entry, *loc_cpu_old_entry; 990 + struct xt_table_info *newinfo; 991 + void *loc_cpu_entry; 1192 992 1193 993 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1194 994 return -EFAULT; ··· 1283 949 goto free_newinfo; 1284 950 } 1285 951 1286 - counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); 1287 - if (!counters) { 1288 - ret = -ENOMEM; 1289 - goto free_newinfo; 1290 - } 1291 - 1292 952 ret = translate_table(tmp.name, tmp.valid_hooks, 1293 953 newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, 1294 954 tmp.hook_entry, tmp.underflow); 1295 955 if (ret != 0) 1296 - goto free_newinfo_counters; 956 + goto free_newinfo; 1297 957 1298 958 duprintf("ip_tables: Translated table\n"); 1299 959 1300 - t = try_then_request_module(xt_find_table_lock(AF_INET, tmp.name), 1301 - "iptable_%s", tmp.name); 1302 - if (!t || IS_ERR(t)) { 1303 - ret = t ? PTR_ERR(t) : -ENOENT; 1304 - goto free_newinfo_counters_untrans; 1305 - } 960 + ret = __do_replace(tmp.name, tmp.valid_hooks, 961 + newinfo, tmp.num_counters, 962 + tmp.counters); 963 + if (ret) 964 + goto free_newinfo_untrans; 965 + return 0; 1306 966 1307 - /* You lied! */ 1308 - if (tmp.valid_hooks != t->valid_hooks) { 1309 - duprintf("Valid hook crap: %08X vs %08X\n", 1310 - tmp.valid_hooks, t->valid_hooks); 1311 - ret = -EINVAL; 1312 - goto put_module; 1313 - } 1314 - 1315 - oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); 1316 - if (!oldinfo) 1317 - goto put_module; 1318 - 1319 - /* Update module usage count based on number of rules */ 1320 - duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n", 1321 - oldinfo->number, oldinfo->initial_entries, newinfo->number); 1322 - if ((oldinfo->number > oldinfo->initial_entries) || 1323 - (newinfo->number <= oldinfo->initial_entries)) 1324 - module_put(t->me); 1325 - if ((oldinfo->number > oldinfo->initial_entries) && 1326 - (newinfo->number <= oldinfo->initial_entries)) 1327 - module_put(t->me); 1328 - 1329 - /* Get the old counters. */ 1330 - get_counters(oldinfo, counters); 1331 - /* Decrease module usage counts and free resource */ 1332 - loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1333 - IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); 1334 - xt_free_table_info(oldinfo); 1335 - if (copy_to_user(tmp.counters, counters, 1336 - sizeof(struct xt_counters) * tmp.num_counters) != 0) 1337 - ret = -EFAULT; 1338 - vfree(counters); 1339 - xt_table_unlock(t); 1340 - return ret; 1341 - 1342 - put_module: 1343 - module_put(t->me); 1344 - xt_table_unlock(t); 1345 - free_newinfo_counters_untrans: 967 + free_newinfo_untrans: 1346 968 IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); 1347 - free_newinfo_counters: 1348 - vfree(counters); 1349 969 free_newinfo: 1350 970 xt_free_table_info(newinfo); 1351 971 return ret; ··· 1328 1040 } 1329 1041 1330 1042 static int 1331 - do_add_counters(void __user *user, unsigned int len) 1043 + do_add_counters(void __user *user, unsigned int len, int compat) 1332 1044 { 1333 1045 unsigned int i; 1334 - struct xt_counters_info tmp, *paddc; 1046 + struct xt_counters_info tmp; 1047 + struct xt_counters *paddc; 1048 + unsigned int num_counters; 1049 + char *name; 1050 + int size; 1051 + void *ptmp; 1335 1052 struct ipt_table *t; 1336 1053 struct xt_table_info *private; 1337 1054 int ret = 0; 1338 1055 void *loc_cpu_entry; 1056 + #ifdef CONFIG_COMPAT 1057 + struct compat_xt_counters_info compat_tmp; 1339 1058 1340 - if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1059 + if (compat) { 1060 + ptmp = &compat_tmp; 1061 + size = sizeof(struct compat_xt_counters_info); 1062 + } else 1063 + #endif 1064 + { 1065 + ptmp = &tmp; 1066 + size = sizeof(struct xt_counters_info); 1067 + } 1068 + 1069 + if (copy_from_user(ptmp, user, size) != 0) 1341 1070 return -EFAULT; 1342 1071 1343 - if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) 1072 + #ifdef CONFIG_COMPAT 1073 + if (compat) { 1074 + num_counters = compat_tmp.num_counters; 1075 + name = compat_tmp.name; 1076 + } else 1077 + #endif 1078 + { 1079 + num_counters = tmp.num_counters; 1080 + name = tmp.name; 1081 + } 1082 + 1083 + if (len != size + num_counters * sizeof(struct xt_counters)) 1344 1084 return -EINVAL; 1345 1085 1346 - paddc = vmalloc_node(len, numa_node_id()); 1086 + paddc = vmalloc_node(len - size, numa_node_id()); 1347 1087 if (!paddc) 1348 1088 return -ENOMEM; 1349 1089 1350 - if (copy_from_user(paddc, user, len) != 0) { 1090 + if (copy_from_user(paddc, user + size, len - size) != 0) { 1351 1091 ret = -EFAULT; 1352 1092 goto free; 1353 1093 } 1354 1094 1355 - t = xt_find_table_lock(AF_INET, tmp.name); 1095 + t = xt_find_table_lock(AF_INET, name); 1356 1096 if (!t || IS_ERR(t)) { 1357 1097 ret = t ? PTR_ERR(t) : -ENOENT; 1358 1098 goto free; ··· 1388 1072 1389 1073 write_lock_bh(&t->lock); 1390 1074 private = t->private; 1391 - if (private->number != paddc->num_counters) { 1075 + if (private->number != num_counters) { 1392 1076 ret = -EINVAL; 1393 1077 goto unlock_up_free; 1394 1078 } ··· 1399 1083 IPT_ENTRY_ITERATE(loc_cpu_entry, 1400 1084 private->size, 1401 1085 add_counter_to_entry, 1402 - paddc->counters, 1086 + paddc, 1403 1087 &i); 1404 1088 unlock_up_free: 1405 1089 write_unlock_bh(&t->lock); ··· 1410 1094 1411 1095 return ret; 1412 1096 } 1097 + 1098 + #ifdef CONFIG_COMPAT 1099 + struct compat_ipt_replace { 1100 + char name[IPT_TABLE_MAXNAMELEN]; 1101 + u32 valid_hooks; 1102 + u32 num_entries; 1103 + u32 size; 1104 + u32 hook_entry[NF_IP_NUMHOOKS]; 1105 + u32 underflow[NF_IP_NUMHOOKS]; 1106 + u32 num_counters; 1107 + compat_uptr_t counters; /* struct ipt_counters * */ 1108 + struct compat_ipt_entry entries[0]; 1109 + }; 1110 + 1111 + static inline int compat_copy_match_to_user(struct ipt_entry_match *m, 1112 + void __user **dstptr, compat_uint_t *size) 1113 + { 1114 + if (m->u.kernel.match->compat) 1115 + return m->u.kernel.match->compat(m, dstptr, size, 1116 + COMPAT_TO_USER); 1117 + else 1118 + return xt_compat_match(m, dstptr, size, COMPAT_TO_USER); 1119 + } 1120 + 1121 + static int compat_copy_entry_to_user(struct ipt_entry *e, 1122 + void __user **dstptr, compat_uint_t *size) 1123 + { 1124 + struct ipt_entry_target __user *t; 1125 + struct compat_ipt_entry __user *ce; 1126 + u_int16_t target_offset, next_offset; 1127 + compat_uint_t origsize; 1128 + int ret; 1129 + 1130 + ret = -EFAULT; 1131 + origsize = *size; 1132 + ce = (struct compat_ipt_entry __user *)*dstptr; 1133 + if (__copy_to_user(ce, e, sizeof(struct ipt_entry))) 1134 + goto out; 1135 + 1136 + *dstptr += sizeof(struct compat_ipt_entry); 1137 + ret = IPT_MATCH_ITERATE(e, compat_copy_match_to_user, dstptr, size); 1138 + target_offset = e->target_offset - (origsize - *size); 1139 + if (ret) 1140 + goto out; 1141 + t = ipt_get_target(e); 1142 + if (t->u.kernel.target->compat) 1143 + ret = t->u.kernel.target->compat(t, dstptr, size, 1144 + COMPAT_TO_USER); 1145 + else 1146 + ret = xt_compat_target(t, dstptr, size, COMPAT_TO_USER); 1147 + if (ret) 1148 + goto out; 1149 + ret = -EFAULT; 1150 + next_offset = e->next_offset - (origsize - *size); 1151 + if (__put_user(target_offset, &ce->target_offset)) 1152 + goto out; 1153 + if (__put_user(next_offset, &ce->next_offset)) 1154 + goto out; 1155 + return 0; 1156 + out: 1157 + return ret; 1158 + } 1159 + 1160 + static inline int 1161 + compat_check_calc_match(struct ipt_entry_match *m, 1162 + const char *name, 1163 + const struct ipt_ip *ip, 1164 + unsigned int hookmask, 1165 + int *size, int *i) 1166 + { 1167 + struct ipt_match *match; 1168 + 1169 + match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, 1170 + m->u.user.revision), 1171 + "ipt_%s", m->u.user.name); 1172 + if (IS_ERR(match) || !match) { 1173 + duprintf("compat_check_calc_match: `%s' not found\n", 1174 + m->u.user.name); 1175 + return match ? PTR_ERR(match) : -ENOENT; 1176 + } 1177 + m->u.kernel.match = match; 1178 + 1179 + if (m->u.kernel.match->compat) 1180 + m->u.kernel.match->compat(m, NULL, size, COMPAT_CALC_SIZE); 1181 + else 1182 + xt_compat_match(m, NULL, size, COMPAT_CALC_SIZE); 1183 + 1184 + (*i)++; 1185 + return 0; 1186 + } 1187 + 1188 + static inline int 1189 + check_compat_entry_size_and_hooks(struct ipt_entry *e, 1190 + struct xt_table_info *newinfo, 1191 + unsigned int *size, 1192 + unsigned char *base, 1193 + unsigned char *limit, 1194 + unsigned int *hook_entries, 1195 + unsigned int *underflows, 1196 + unsigned int *i, 1197 + const char *name) 1198 + { 1199 + struct ipt_entry_target *t; 1200 + struct ipt_target *target; 1201 + u_int16_t entry_offset; 1202 + int ret, off, h, j; 1203 + 1204 + duprintf("check_compat_entry_size_and_hooks %p\n", e); 1205 + if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 1206 + || (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) { 1207 + duprintf("Bad offset %p, limit = %p\n", e, limit); 1208 + return -EINVAL; 1209 + } 1210 + 1211 + if (e->next_offset < sizeof(struct compat_ipt_entry) + 1212 + sizeof(struct compat_xt_entry_target)) { 1213 + duprintf("checking: element %p size %u\n", 1214 + e, e->next_offset); 1215 + return -EINVAL; 1216 + } 1217 + 1218 + if (!ip_checkentry(&e->ip)) { 1219 + duprintf("ip_tables: ip check failed %p %s.\n", e, name); 1220 + return -EINVAL; 1221 + } 1222 + 1223 + off = 0; 1224 + entry_offset = (void *)e - (void *)base; 1225 + j = 0; 1226 + ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip, 1227 + e->comefrom, &off, &j); 1228 + if (ret != 0) 1229 + goto out; 1230 + 1231 + t = ipt_get_target(e); 1232 + target = try_then_request_module(xt_find_target(AF_INET, 1233 + t->u.user.name, 1234 + t->u.user.revision), 1235 + "ipt_%s", t->u.user.name); 1236 + if (IS_ERR(target) || !target) { 1237 + duprintf("check_entry: `%s' not found\n", t->u.user.name); 1238 + ret = target ? PTR_ERR(target) : -ENOENT; 1239 + goto out; 1240 + } 1241 + t->u.kernel.target = target; 1242 + 1243 + if (t->u.kernel.target->compat) 1244 + t->u.kernel.target->compat(t, NULL, &off, COMPAT_CALC_SIZE); 1245 + else 1246 + xt_compat_target(t, NULL, &off, COMPAT_CALC_SIZE); 1247 + *size += off; 1248 + ret = compat_add_offset(entry_offset, off); 1249 + if (ret) 1250 + goto out; 1251 + 1252 + /* Check hooks & underflows */ 1253 + for (h = 0; h < NF_IP_NUMHOOKS; h++) { 1254 + if ((unsigned char *)e - base == hook_entries[h]) 1255 + newinfo->hook_entry[h] = hook_entries[h]; 1256 + if ((unsigned char *)e - base == underflows[h]) 1257 + newinfo->underflow[h] = underflows[h]; 1258 + } 1259 + 1260 + /* Clear counters and comefrom */ 1261 + e->counters = ((struct ipt_counters) { 0, 0 }); 1262 + e->comefrom = 0; 1263 + 1264 + (*i)++; 1265 + return 0; 1266 + out: 1267 + IPT_MATCH_ITERATE(e, cleanup_match, &j); 1268 + return ret; 1269 + } 1270 + 1271 + static inline int compat_copy_match_from_user(struct ipt_entry_match *m, 1272 + void **dstptr, compat_uint_t *size, const char *name, 1273 + const struct ipt_ip *ip, unsigned int hookmask) 1274 + { 1275 + struct ipt_entry_match *dm; 1276 + struct ipt_match *match; 1277 + int ret; 1278 + 1279 + dm = (struct ipt_entry_match *)*dstptr; 1280 + match = m->u.kernel.match; 1281 + if (match->compat) 1282 + match->compat(m, dstptr, size, COMPAT_FROM_USER); 1283 + else 1284 + xt_compat_match(m, dstptr, size, COMPAT_FROM_USER); 1285 + 1286 + ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), 1287 + name, hookmask, ip->proto, 1288 + ip->invflags & IPT_INV_PROTO); 1289 + if (ret) 1290 + return ret; 1291 + 1292 + if (m->u.kernel.match->checkentry 1293 + && !m->u.kernel.match->checkentry(name, ip, match, dm->data, 1294 + dm->u.match_size - sizeof(*dm), 1295 + hookmask)) { 1296 + duprintf("ip_tables: check failed for `%s'.\n", 1297 + m->u.kernel.match->name); 1298 + return -EINVAL; 1299 + } 1300 + return 0; 1301 + } 1302 + 1303 + static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, 1304 + unsigned int *size, const char *name, 1305 + struct xt_table_info *newinfo, unsigned char *base) 1306 + { 1307 + struct ipt_entry_target *t; 1308 + struct ipt_target *target; 1309 + struct ipt_entry *de; 1310 + unsigned int origsize; 1311 + int ret, h; 1312 + 1313 + ret = 0; 1314 + origsize = *size; 1315 + de = (struct ipt_entry *)*dstptr; 1316 + memcpy(de, e, sizeof(struct ipt_entry)); 1317 + 1318 + *dstptr += sizeof(struct compat_ipt_entry); 1319 + ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, 1320 + name, &de->ip, de->comefrom); 1321 + if (ret) 1322 + goto out; 1323 + de->target_offset = e->target_offset - (origsize - *size); 1324 + t = ipt_get_target(e); 1325 + target = t->u.kernel.target; 1326 + if (target->compat) 1327 + target->compat(t, dstptr, size, COMPAT_FROM_USER); 1328 + else 1329 + xt_compat_target(t, dstptr, size, COMPAT_FROM_USER); 1330 + 1331 + de->next_offset = e->next_offset - (origsize - *size); 1332 + for (h = 0; h < NF_IP_NUMHOOKS; h++) { 1333 + if ((unsigned char *)de - base < newinfo->hook_entry[h]) 1334 + newinfo->hook_entry[h] -= origsize - *size; 1335 + if ((unsigned char *)de - base < newinfo->underflow[h]) 1336 + newinfo->underflow[h] -= origsize - *size; 1337 + } 1338 + 1339 + t = ipt_get_target(de); 1340 + target = t->u.kernel.target; 1341 + ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), 1342 + name, e->comefrom, e->ip.proto, 1343 + e->ip.invflags & IPT_INV_PROTO); 1344 + if (ret) 1345 + goto out; 1346 + 1347 + ret = -EINVAL; 1348 + if (t->u.kernel.target == &ipt_standard_target) { 1349 + if (!standard_check(t, *size)) 1350 + goto out; 1351 + } else if (t->u.kernel.target->checkentry 1352 + && !t->u.kernel.target->checkentry(name, de, target, 1353 + t->data, t->u.target_size - sizeof(*t), 1354 + de->comefrom)) { 1355 + duprintf("ip_tables: compat: check failed for `%s'.\n", 1356 + t->u.kernel.target->name); 1357 + goto out; 1358 + } 1359 + ret = 0; 1360 + out: 1361 + return ret; 1362 + } 1363 + 1364 + static int 1365 + translate_compat_table(const char *name, 1366 + unsigned int valid_hooks, 1367 + struct xt_table_info **pinfo, 1368 + void **pentry0, 1369 + unsigned int total_size, 1370 + unsigned int number, 1371 + unsigned int *hook_entries, 1372 + unsigned int *underflows) 1373 + { 1374 + unsigned int i; 1375 + struct xt_table_info *newinfo, *info; 1376 + void *pos, *entry0, *entry1; 1377 + unsigned int size; 1378 + int ret; 1379 + 1380 + info = *pinfo; 1381 + entry0 = *pentry0; 1382 + size = total_size; 1383 + info->number = number; 1384 + 1385 + /* Init all hooks to impossible value. */ 1386 + for (i = 0; i < NF_IP_NUMHOOKS; i++) { 1387 + info->hook_entry[i] = 0xFFFFFFFF; 1388 + info->underflow[i] = 0xFFFFFFFF; 1389 + } 1390 + 1391 + duprintf("translate_compat_table: size %u\n", info->size); 1392 + i = 0; 1393 + xt_compat_lock(AF_INET); 1394 + /* Walk through entries, checking offsets. */ 1395 + ret = IPT_ENTRY_ITERATE(entry0, total_size, 1396 + check_compat_entry_size_and_hooks, 1397 + info, &size, entry0, 1398 + entry0 + total_size, 1399 + hook_entries, underflows, &i, name); 1400 + if (ret != 0) 1401 + goto out_unlock; 1402 + 1403 + ret = -EINVAL; 1404 + if (i != number) { 1405 + duprintf("translate_compat_table: %u not %u entries\n", 1406 + i, number); 1407 + goto out_unlock; 1408 + } 1409 + 1410 + /* Check hooks all assigned */ 1411 + for (i = 0; i < NF_IP_NUMHOOKS; i++) { 1412 + /* Only hooks which are valid */ 1413 + if (!(valid_hooks & (1 << i))) 1414 + continue; 1415 + if (info->hook_entry[i] == 0xFFFFFFFF) { 1416 + duprintf("Invalid hook entry %u %u\n", 1417 + i, hook_entries[i]); 1418 + goto out_unlock; 1419 + } 1420 + if (info->underflow[i] == 0xFFFFFFFF) { 1421 + duprintf("Invalid underflow %u %u\n", 1422 + i, underflows[i]); 1423 + goto out_unlock; 1424 + } 1425 + } 1426 + 1427 + ret = -ENOMEM; 1428 + newinfo = xt_alloc_table_info(size); 1429 + if (!newinfo) 1430 + goto out_unlock; 1431 + 1432 + newinfo->number = number; 1433 + for (i = 0; i < NF_IP_NUMHOOKS; i++) { 1434 + newinfo->hook_entry[i] = info->hook_entry[i]; 1435 + newinfo->underflow[i] = info->underflow[i]; 1436 + } 1437 + entry1 = newinfo->entries[raw_smp_processor_id()]; 1438 + pos = entry1; 1439 + size = total_size; 1440 + ret = IPT_ENTRY_ITERATE(entry0, total_size, 1441 + compat_copy_entry_from_user, &pos, &size, 1442 + name, newinfo, entry1); 1443 + compat_flush_offsets(); 1444 + xt_compat_unlock(AF_INET); 1445 + if (ret) 1446 + goto free_newinfo; 1447 + 1448 + ret = -ELOOP; 1449 + if (!mark_source_chains(newinfo, valid_hooks, entry1)) 1450 + goto free_newinfo; 1451 + 1452 + /* And one copy for every other CPU */ 1453 + for_each_cpu(i) 1454 + if (newinfo->entries[i] && newinfo->entries[i] != entry1) 1455 + memcpy(newinfo->entries[i], entry1, newinfo->size); 1456 + 1457 + *pinfo = newinfo; 1458 + *pentry0 = entry1; 1459 + xt_free_table_info(info); 1460 + return 0; 1461 + 1462 + free_newinfo: 1463 + xt_free_table_info(newinfo); 1464 + out: 1465 + return ret; 1466 + out_unlock: 1467 + xt_compat_unlock(AF_INET); 1468 + goto out; 1469 + } 1470 + 1471 + static int 1472 + compat_do_replace(void __user *user, unsigned int len) 1473 + { 1474 + int ret; 1475 + struct compat_ipt_replace tmp; 1476 + struct xt_table_info *newinfo; 1477 + void *loc_cpu_entry; 1478 + 1479 + if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1480 + return -EFAULT; 1481 + 1482 + /* Hack: Causes ipchains to give correct error msg --RR */ 1483 + if (len != sizeof(tmp) + tmp.size) 1484 + return -ENOPROTOOPT; 1485 + 1486 + /* overflow check */ 1487 + if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - 1488 + SMP_CACHE_BYTES) 1489 + return -ENOMEM; 1490 + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) 1491 + return -ENOMEM; 1492 + 1493 + newinfo = xt_alloc_table_info(tmp.size); 1494 + if (!newinfo) 1495 + return -ENOMEM; 1496 + 1497 + /* choose the copy that is our node/cpu */ 1498 + loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; 1499 + if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), 1500 + tmp.size) != 0) { 1501 + ret = -EFAULT; 1502 + goto free_newinfo; 1503 + } 1504 + 1505 + ret = translate_compat_table(tmp.name, tmp.valid_hooks, 1506 + &newinfo, &loc_cpu_entry, tmp.size, 1507 + tmp.num_entries, tmp.hook_entry, tmp.underflow); 1508 + if (ret != 0) 1509 + goto free_newinfo; 1510 + 1511 + duprintf("compat_do_replace: Translated table\n"); 1512 + 1513 + ret = __do_replace(tmp.name, tmp.valid_hooks, 1514 + newinfo, tmp.num_counters, 1515 + compat_ptr(tmp.counters)); 1516 + if (ret) 1517 + goto free_newinfo_untrans; 1518 + return 0; 1519 + 1520 + free_newinfo_untrans: 1521 + IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); 1522 + free_newinfo: 1523 + xt_free_table_info(newinfo); 1524 + return ret; 1525 + } 1526 + 1527 + static int 1528 + compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, 1529 + unsigned int len) 1530 + { 1531 + int ret; 1532 + 1533 + if (!capable(CAP_NET_ADMIN)) 1534 + return -EPERM; 1535 + 1536 + switch (cmd) { 1537 + case IPT_SO_SET_REPLACE: 1538 + ret = compat_do_replace(user, len); 1539 + break; 1540 + 1541 + case IPT_SO_SET_ADD_COUNTERS: 1542 + ret = do_add_counters(user, len, 1); 1543 + break; 1544 + 1545 + default: 1546 + duprintf("do_ipt_set_ctl: unknown request %i\n", cmd); 1547 + ret = -EINVAL; 1548 + } 1549 + 1550 + return ret; 1551 + } 1552 + 1553 + struct compat_ipt_get_entries 1554 + { 1555 + char name[IPT_TABLE_MAXNAMELEN]; 1556 + compat_uint_t size; 1557 + struct compat_ipt_entry entrytable[0]; 1558 + }; 1559 + 1560 + static int compat_copy_entries_to_user(unsigned int total_size, 1561 + struct ipt_table *table, void __user *userptr) 1562 + { 1563 + unsigned int off, num; 1564 + struct compat_ipt_entry e; 1565 + struct xt_counters *counters; 1566 + struct xt_table_info *private = table->private; 1567 + void __user *pos; 1568 + unsigned int size; 1569 + int ret = 0; 1570 + void *loc_cpu_entry; 1571 + 1572 + counters = alloc_counters(table); 1573 + if (IS_ERR(counters)) 1574 + return PTR_ERR(counters); 1575 + 1576 + /* choose the copy that is on our node/cpu, ... 1577 + * This choice is lazy (because current thread is 1578 + * allowed to migrate to another cpu) 1579 + */ 1580 + loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1581 + pos = userptr; 1582 + size = total_size; 1583 + ret = IPT_ENTRY_ITERATE(loc_cpu_entry, total_size, 1584 + compat_copy_entry_to_user, &pos, &size); 1585 + if (ret) 1586 + goto free_counters; 1587 + 1588 + /* ... then go back and fix counters and names */ 1589 + for (off = 0, num = 0; off < size; off += e.next_offset, num++) { 1590 + unsigned int i; 1591 + struct ipt_entry_match m; 1592 + struct ipt_entry_target t; 1593 + 1594 + ret = -EFAULT; 1595 + if (copy_from_user(&e, userptr + off, 1596 + sizeof(struct compat_ipt_entry))) 1597 + goto free_counters; 1598 + if (copy_to_user(userptr + off + 1599 + offsetof(struct compat_ipt_entry, counters), 1600 + &counters[num], sizeof(counters[num]))) 1601 + goto free_counters; 1602 + 1603 + for (i = sizeof(struct compat_ipt_entry); 1604 + i < e.target_offset; i += m.u.match_size) { 1605 + if (copy_from_user(&m, userptr + off + i, 1606 + sizeof(struct ipt_entry_match))) 1607 + goto free_counters; 1608 + if (copy_to_user(userptr + off + i + 1609 + offsetof(struct ipt_entry_match, u.user.name), 1610 + m.u.kernel.match->name, 1611 + strlen(m.u.kernel.match->name) + 1)) 1612 + goto free_counters; 1613 + } 1614 + 1615 + if (copy_from_user(&t, userptr + off + e.target_offset, 1616 + sizeof(struct ipt_entry_target))) 1617 + goto free_counters; 1618 + if (copy_to_user(userptr + off + e.target_offset + 1619 + offsetof(struct ipt_entry_target, u.user.name), 1620 + t.u.kernel.target->name, 1621 + strlen(t.u.kernel.target->name) + 1)) 1622 + goto free_counters; 1623 + } 1624 + ret = 0; 1625 + free_counters: 1626 + vfree(counters); 1627 + return ret; 1628 + } 1629 + 1630 + static int 1631 + compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len) 1632 + { 1633 + int ret; 1634 + struct compat_ipt_get_entries get; 1635 + struct ipt_table *t; 1636 + 1637 + 1638 + if (*len < sizeof(get)) { 1639 + duprintf("compat_get_entries: %u < %u\n", 1640 + *len, (unsigned int)sizeof(get)); 1641 + return -EINVAL; 1642 + } 1643 + 1644 + if (copy_from_user(&get, uptr, sizeof(get)) != 0) 1645 + return -EFAULT; 1646 + 1647 + if (*len != sizeof(struct compat_ipt_get_entries) + get.size) { 1648 + duprintf("compat_get_entries: %u != %u\n", *len, 1649 + (unsigned int)(sizeof(struct compat_ipt_get_entries) + 1650 + get.size)); 1651 + return -EINVAL; 1652 + } 1653 + 1654 + xt_compat_lock(AF_INET); 1655 + t = xt_find_table_lock(AF_INET, get.name); 1656 + if (t && !IS_ERR(t)) { 1657 + struct xt_table_info *private = t->private; 1658 + struct xt_table_info info; 1659 + duprintf("t->private->number = %u\n", 1660 + private->number); 1661 + ret = compat_table_info(private, &info); 1662 + if (!ret && get.size == info.size) { 1663 + ret = compat_copy_entries_to_user(private->size, 1664 + t, uptr->entrytable); 1665 + } else if (!ret) { 1666 + duprintf("compat_get_entries: I've got %u not %u!\n", 1667 + private->size, 1668 + get.size); 1669 + ret = -EINVAL; 1670 + } 1671 + compat_flush_offsets(); 1672 + module_put(t->me); 1673 + xt_table_unlock(t); 1674 + } else 1675 + ret = t ? PTR_ERR(t) : -ENOENT; 1676 + 1677 + xt_compat_unlock(AF_INET); 1678 + return ret; 1679 + } 1680 + 1681 + static int 1682 + compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) 1683 + { 1684 + int ret; 1685 + 1686 + switch (cmd) { 1687 + case IPT_SO_GET_INFO: 1688 + ret = get_info(user, len, 1); 1689 + break; 1690 + case IPT_SO_GET_ENTRIES: 1691 + ret = compat_get_entries(user, len); 1692 + break; 1693 + default: 1694 + duprintf("compat_do_ipt_get_ctl: unknown request %i\n", cmd); 1695 + ret = -EINVAL; 1696 + } 1697 + return ret; 1698 + } 1699 + #endif 1413 1700 1414 1701 static int 1415 1702 do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) ··· 2028 1109 break; 2029 1110 2030 1111 case IPT_SO_SET_ADD_COUNTERS: 2031 - ret = do_add_counters(user, len); 1112 + ret = do_add_counters(user, len, 0); 2032 1113 break; 2033 1114 2034 1115 default: ··· 2048 1129 return -EPERM; 2049 1130 2050 1131 switch (cmd) { 2051 - case IPT_SO_GET_INFO: { 2052 - char name[IPT_TABLE_MAXNAMELEN]; 2053 - struct ipt_table *t; 2054 - 2055 - if (*len != sizeof(struct ipt_getinfo)) { 2056 - duprintf("length %u != %u\n", *len, 2057 - sizeof(struct ipt_getinfo)); 2058 - ret = -EINVAL; 2059 - break; 2060 - } 2061 - 2062 - if (copy_from_user(name, user, sizeof(name)) != 0) { 2063 - ret = -EFAULT; 2064 - break; 2065 - } 2066 - name[IPT_TABLE_MAXNAMELEN-1] = '\0'; 2067 - 2068 - t = try_then_request_module(xt_find_table_lock(AF_INET, name), 2069 - "iptable_%s", name); 2070 - if (t && !IS_ERR(t)) { 2071 - struct ipt_getinfo info; 2072 - struct xt_table_info *private = t->private; 2073 - 2074 - info.valid_hooks = t->valid_hooks; 2075 - memcpy(info.hook_entry, private->hook_entry, 2076 - sizeof(info.hook_entry)); 2077 - memcpy(info.underflow, private->underflow, 2078 - sizeof(info.underflow)); 2079 - info.num_entries = private->number; 2080 - info.size = private->size; 2081 - memcpy(info.name, name, sizeof(info.name)); 2082 - 2083 - if (copy_to_user(user, &info, *len) != 0) 2084 - ret = -EFAULT; 2085 - else 2086 - ret = 0; 2087 - xt_table_unlock(t); 2088 - module_put(t->me); 2089 - } else 2090 - ret = t ? PTR_ERR(t) : -ENOENT; 2091 - } 2092 - break; 2093 - 2094 - case IPT_SO_GET_ENTRIES: { 2095 - struct ipt_get_entries get; 2096 - 2097 - if (*len < sizeof(get)) { 2098 - duprintf("get_entries: %u < %u\n", *len, sizeof(get)); 2099 - ret = -EINVAL; 2100 - } else if (copy_from_user(&get, user, sizeof(get)) != 0) { 2101 - ret = -EFAULT; 2102 - } else if (*len != sizeof(struct ipt_get_entries) + get.size) { 2103 - duprintf("get_entries: %u != %u\n", *len, 2104 - sizeof(struct ipt_get_entries) + get.size); 2105 - ret = -EINVAL; 2106 - } else 2107 - ret = get_entries(&get, user); 1132 + case IPT_SO_GET_INFO: 1133 + ret = get_info(user, len, 0); 2108 1134 break; 2109 - } 1135 + 1136 + case IPT_SO_GET_ENTRIES: 1137 + ret = get_entries(user, len); 1138 + break; 2110 1139 2111 1140 case IPT_SO_GET_REVISION_MATCH: 2112 1141 case IPT_SO_GET_REVISION_TARGET: { ··· 2203 1336 .name = IPT_STANDARD_TARGET, 2204 1337 .targetsize = sizeof(int), 2205 1338 .family = AF_INET, 1339 + #ifdef CONFIG_COMPAT 1340 + .compat = &compat_ipt_standard_fn, 1341 + #endif 2206 1342 }; 2207 1343 2208 1344 static struct ipt_target ipt_error_target = { ··· 2220 1350 .set_optmin = IPT_BASE_CTL, 2221 1351 .set_optmax = IPT_SO_SET_MAX+1, 2222 1352 .set = do_ipt_set_ctl, 1353 + #ifdef CONFIG_COMPAT 1354 + .compat_set = compat_do_ipt_set_ctl, 1355 + #endif 2223 1356 .get_optmin = IPT_BASE_CTL, 2224 1357 .get_optmax = IPT_SO_GET_MAX+1, 2225 1358 .get = do_ipt_get_ctl, 1359 + #ifdef CONFIG_COMPAT 1360 + .compat_get = compat_do_ipt_get_ctl, 1361 + #endif 2226 1362 }; 2227 1363 2228 1364 static struct ipt_match icmp_matchstruct = {
+53 -28
net/ipv4/netfilter/ipt_esp.c net/netfilter/xt_esp.c
··· 9 9 10 10 #include <linux/module.h> 11 11 #include <linux/skbuff.h> 12 + #include <linux/in.h> 12 13 #include <linux/ip.h> 13 14 14 - #include <linux/netfilter_ipv4/ipt_esp.h> 15 + #include <linux/netfilter/xt_esp.h> 16 + #include <linux/netfilter/x_tables.h> 17 + 15 18 #include <linux/netfilter_ipv4/ip_tables.h> 19 + #include <linux/netfilter_ipv6/ip6_tables.h> 16 20 17 21 MODULE_LICENSE("GPL"); 18 22 MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>"); 19 - MODULE_DESCRIPTION("iptables ESP SPI match module"); 23 + MODULE_DESCRIPTION("x_tables ESP SPI match module"); 24 + MODULE_ALIAS("ipt_esp"); 25 + MODULE_ALIAS("ip6t_esp"); 20 26 21 - #ifdef DEBUG_CONNTRACK 27 + #if 0 22 28 #define duprintf(format, args...) printk(format , ## args) 23 29 #else 24 30 #define duprintf(format, args...) ··· 34 28 static inline int 35 29 spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert) 36 30 { 37 - int r=0; 38 - duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', 39 - min,spi,max); 40 - r=(spi >= min && spi <= max) ^ invert; 41 - duprintf(" result %s\n",r? "PASS" : "FAILED"); 31 + int r = 0; 32 + duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ', 33 + min, spi, max); 34 + r = (spi >= min && spi <= max) ^ invert; 35 + duprintf(" result %s\n", r ? "PASS" : "FAILED"); 42 36 return r; 43 37 } 44 38 ··· 53 47 int *hotdrop) 54 48 { 55 49 struct ip_esp_hdr _esp, *eh; 56 - const struct ipt_esp *espinfo = matchinfo; 50 + const struct xt_esp *espinfo = matchinfo; 57 51 58 52 /* Must not be a fragment. */ 59 53 if (offset) 60 54 return 0; 61 55 62 - eh = skb_header_pointer(skb, protoff, 63 - sizeof(_esp), &_esp); 56 + eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp); 64 57 if (eh == NULL) { 65 58 /* We've been asked to examine this packet, and we 66 59 * can't. Hence, no choice but to drop. ··· 69 64 return 0; 70 65 } 71 66 72 - return spi_match(espinfo->spis[0], espinfo->spis[1], 73 - ntohl(eh->spi), 74 - !!(espinfo->invflags & IPT_ESP_INV_SPI)); 67 + return spi_match(espinfo->spis[0], espinfo->spis[1], ntohl(eh->spi), 68 + !!(espinfo->invflags & XT_ESP_INV_SPI)); 75 69 } 76 70 77 71 /* Called when user tries to insert an entry of this type. */ ··· 82 78 unsigned int matchinfosize, 83 79 unsigned int hook_mask) 84 80 { 85 - const struct ipt_esp *espinfo = matchinfo; 81 + const struct xt_esp *espinfo = matchinfo; 86 82 87 - /* Must specify no unknown invflags */ 88 - if (espinfo->invflags & ~IPT_ESP_INV_MASK) { 89 - duprintf("ipt_esp: unknown flags %X\n", espinfo->invflags); 83 + if (espinfo->invflags & ~XT_ESP_INV_MASK) { 84 + duprintf("xt_esp: unknown flags %X\n", espinfo->invflags); 90 85 return 0; 91 86 } 87 + 92 88 return 1; 93 89 } 94 90 95 - static struct ipt_match esp_match = { 91 + static struct xt_match esp_match = { 96 92 .name = "esp", 97 - .match = match, 98 - .matchsize = sizeof(struct ipt_esp), 93 + .family = AF_INET, 99 94 .proto = IPPROTO_ESP, 100 - .checkentry = checkentry, 95 + .match = &match, 96 + .matchsize = sizeof(struct xt_esp), 97 + .checkentry = &checkentry, 101 98 .me = THIS_MODULE, 102 99 }; 103 100 104 - static int __init ipt_esp_init(void) 101 + static struct xt_match esp6_match = { 102 + .name = "esp", 103 + .family = AF_INET6, 104 + .proto = IPPROTO_ESP, 105 + .match = &match, 106 + .matchsize = sizeof(struct xt_esp), 107 + .checkentry = &checkentry, 108 + .me = THIS_MODULE, 109 + }; 110 + 111 + static int __init xt_esp_init(void) 105 112 { 106 - return ipt_register_match(&esp_match); 113 + int ret; 114 + ret = xt_register_match(&esp_match); 115 + if (ret) 116 + return ret; 117 + 118 + ret = xt_register_match(&esp6_match); 119 + if (ret) 120 + xt_unregister_match(&esp_match); 121 + 122 + return ret; 107 123 } 108 124 109 - static void __exit ipt_esp_fini(void) 125 + static void __exit xt_esp_cleanup(void) 110 126 { 111 - ipt_unregister_match(&esp_match); 127 + xt_unregister_match(&esp_match); 128 + xt_unregister_match(&esp6_match); 112 129 } 113 130 114 - module_init(ipt_esp_init); 115 - module_exit(ipt_esp_fini); 131 + module_init(xt_esp_init); 132 + module_exit(xt_esp_cleanup);
-195
net/ipv4/netfilter/ipt_multiport.c
··· 1 - /* Kernel module to match one of a list of TCP/UDP ports: ports are in 2 - the same place so we can treat them as equal. */ 3 - 4 - /* (C) 1999-2001 Paul `Rusty' Russell 5 - * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 - */ 11 - 12 - #include <linux/module.h> 13 - #include <linux/types.h> 14 - #include <linux/udp.h> 15 - #include <linux/skbuff.h> 16 - 17 - #include <linux/netfilter_ipv4/ipt_multiport.h> 18 - #include <linux/netfilter_ipv4/ip_tables.h> 19 - 20 - MODULE_LICENSE("GPL"); 21 - MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 22 - MODULE_DESCRIPTION("iptables multiple port match module"); 23 - 24 - #if 0 25 - #define duprintf(format, args...) printk(format , ## args) 26 - #else 27 - #define duprintf(format, args...) 28 - #endif 29 - 30 - /* Returns 1 if the port is matched by the test, 0 otherwise. */ 31 - static inline int 32 - ports_match(const u_int16_t *portlist, enum ipt_multiport_flags flags, 33 - u_int8_t count, u_int16_t src, u_int16_t dst) 34 - { 35 - unsigned int i; 36 - for (i=0; i<count; i++) { 37 - if (flags != IPT_MULTIPORT_DESTINATION 38 - && portlist[i] == src) 39 - return 1; 40 - 41 - if (flags != IPT_MULTIPORT_SOURCE 42 - && portlist[i] == dst) 43 - return 1; 44 - } 45 - 46 - return 0; 47 - } 48 - 49 - /* Returns 1 if the port is matched by the test, 0 otherwise. */ 50 - static inline int 51 - ports_match_v1(const struct ipt_multiport_v1 *minfo, 52 - u_int16_t src, u_int16_t dst) 53 - { 54 - unsigned int i; 55 - u_int16_t s, e; 56 - 57 - for (i=0; i < minfo->count; i++) { 58 - s = minfo->ports[i]; 59 - 60 - if (minfo->pflags[i]) { 61 - /* range port matching */ 62 - e = minfo->ports[++i]; 63 - duprintf("src or dst matches with %d-%d?\n", s, e); 64 - 65 - if (minfo->flags == IPT_MULTIPORT_SOURCE 66 - && src >= s && src <= e) 67 - return 1 ^ minfo->invert; 68 - if (minfo->flags == IPT_MULTIPORT_DESTINATION 69 - && dst >= s && dst <= e) 70 - return 1 ^ minfo->invert; 71 - if (minfo->flags == IPT_MULTIPORT_EITHER 72 - && ((dst >= s && dst <= e) 73 - || (src >= s && src <= e))) 74 - return 1 ^ minfo->invert; 75 - } else { 76 - /* exact port matching */ 77 - duprintf("src or dst matches with %d?\n", s); 78 - 79 - if (minfo->flags == IPT_MULTIPORT_SOURCE 80 - && src == s) 81 - return 1 ^ minfo->invert; 82 - if (minfo->flags == IPT_MULTIPORT_DESTINATION 83 - && dst == s) 84 - return 1 ^ minfo->invert; 85 - if (minfo->flags == IPT_MULTIPORT_EITHER 86 - && (src == s || dst == s)) 87 - return 1 ^ minfo->invert; 88 - } 89 - } 90 - 91 - return minfo->invert; 92 - } 93 - 94 - static int 95 - match(const struct sk_buff *skb, 96 - const struct net_device *in, 97 - const struct net_device *out, 98 - const struct xt_match *match, 99 - const void *matchinfo, 100 - int offset, 101 - unsigned int protoff, 102 - int *hotdrop) 103 - { 104 - u16 _ports[2], *pptr; 105 - const struct ipt_multiport *multiinfo = matchinfo; 106 - 107 - if (offset) 108 - return 0; 109 - 110 - pptr = skb_header_pointer(skb, protoff, 111 - sizeof(_ports), _ports); 112 - if (pptr == NULL) { 113 - /* We've been asked to examine this packet, and we 114 - * can't. Hence, no choice but to drop. 115 - */ 116 - duprintf("ipt_multiport:" 117 - " Dropping evil offset=0 tinygram.\n"); 118 - *hotdrop = 1; 119 - return 0; 120 - } 121 - 122 - return ports_match(multiinfo->ports, 123 - multiinfo->flags, multiinfo->count, 124 - ntohs(pptr[0]), ntohs(pptr[1])); 125 - } 126 - 127 - static int 128 - match_v1(const struct sk_buff *skb, 129 - const struct net_device *in, 130 - const struct net_device *out, 131 - const struct xt_match *match, 132 - const void *matchinfo, 133 - int offset, 134 - unsigned int protoff, 135 - int *hotdrop) 136 - { 137 - u16 _ports[2], *pptr; 138 - const struct ipt_multiport_v1 *multiinfo = matchinfo; 139 - 140 - if (offset) 141 - return 0; 142 - 143 - pptr = skb_header_pointer(skb, protoff, 144 - sizeof(_ports), _ports); 145 - if (pptr == NULL) { 146 - /* We've been asked to examine this packet, and we 147 - * can't. Hence, no choice but to drop. 148 - */ 149 - duprintf("ipt_multiport:" 150 - " Dropping evil offset=0 tinygram.\n"); 151 - *hotdrop = 1; 152 - return 0; 153 - } 154 - 155 - return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1])); 156 - } 157 - 158 - static struct ipt_match multiport_match = { 159 - .name = "multiport", 160 - .revision = 0, 161 - .match = match, 162 - .matchsize = sizeof(struct ipt_multiport), 163 - .me = THIS_MODULE, 164 - }; 165 - 166 - static struct ipt_match multiport_match_v1 = { 167 - .name = "multiport", 168 - .revision = 1, 169 - .match = match_v1, 170 - .matchsize = sizeof(struct ipt_multiport_v1), 171 - .me = THIS_MODULE, 172 - }; 173 - 174 - static int __init ipt_multiport_init(void) 175 - { 176 - int err; 177 - 178 - err = ipt_register_match(&multiport_match); 179 - if (!err) { 180 - err = ipt_register_match(&multiport_match_v1); 181 - if (err) 182 - ipt_unregister_match(&multiport_match); 183 - } 184 - 185 - return err; 186 - } 187 - 188 - static void __exit ipt_multiport_fini(void) 189 - { 190 - ipt_unregister_match(&multiport_match); 191 - ipt_unregister_match(&multiport_match_v1); 192 - } 193 - 194 - module_init(ipt_multiport_init); 195 - module_exit(ipt_multiport_fini);
+9 -6
net/ipv4/xfrm4_input.c
··· 68 68 { 69 69 int err; 70 70 u32 spi, seq; 71 - struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; 71 + struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; 72 72 struct xfrm_state *x; 73 73 int xfrm_nr = 0; 74 74 int decaps = 0; ··· 90 90 if (unlikely(x->km.state != XFRM_STATE_VALID)) 91 91 goto drop_unlock; 92 92 93 + if (x->encap->encap_type != encap_type) 94 + goto drop_unlock; 95 + 93 96 if (x->props.replay_window && xfrm_replay_check(x, seq)) 94 97 goto drop_unlock; 95 98 96 99 if (xfrm_state_check_expire(x)) 97 100 goto drop_unlock; 98 101 99 - xfrm_vec[xfrm_nr].decap.decap_type = encap_type; 100 - if (x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb)) 102 + if (x->type->input(x, skb)) 101 103 goto drop_unlock; 102 104 103 105 /* only the first xfrm gets the encap type */ ··· 113 111 114 112 spin_unlock(&x->lock); 115 113 116 - xfrm_vec[xfrm_nr++].xvec = x; 114 + xfrm_vec[xfrm_nr++] = x; 117 115 118 116 iph = skb->nh.iph; 119 117 ··· 155 153 if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) 156 154 goto drop; 157 155 158 - memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state)); 156 + memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec, 157 + xfrm_nr * sizeof(xfrm_vec[0])); 159 158 skb->sp->len += xfrm_nr; 160 159 161 160 nf_reset(skb); ··· 187 184 xfrm_state_put(x); 188 185 drop: 189 186 while (--xfrm_nr >= 0) 190 - xfrm_state_put(xfrm_vec[xfrm_nr].xvec); 187 + xfrm_state_put(xfrm_vec[xfrm_nr]); 191 188 192 189 kfree_skb(skb); 193 190 return 0;
+1 -1
net/ipv4/xfrm4_tunnel.c
··· 21 21 return 0; 22 22 } 23 23 24 - static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) 24 + static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb) 25 25 { 26 26 return 0; 27 27 }
+1 -1
net/ipv6/ah6.c
··· 229 229 return err; 230 230 } 231 231 232 - static int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) 232 + static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) 233 233 { 234 234 /* 235 235 * Before process AH
+1 -1
net/ipv6/esp6.c
··· 130 130 return err; 131 131 } 132 132 133 - static int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) 133 + static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) 134 134 { 135 135 struct ipv6hdr *iph; 136 136 struct ipv6_esp_hdr *esph;
+1 -1
net/ipv6/ipcomp6.c
··· 63 63 static int ipcomp6_scratch_users; 64 64 static LIST_HEAD(ipcomp6_tfms_list); 65 65 66 - static int ipcomp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) 66 + static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) 67 67 { 68 68 int err = 0; 69 69 u8 nexthdr = 0;
+3 -13
net/ipv6/netfilter/Kconfig
··· 87 87 88 88 To compile it as a module, choose M here. If unsure, say N. 89 89 90 - config IP6_NF_MATCH_MULTIPORT 91 - tristate "Multiple port match support" 92 - depends on IP6_NF_IPTABLES 93 - help 94 - Multiport matching allows you to match TCP or UDP packets based on 95 - a series of source or destination ports: normally a rule can only 96 - match a single range of ports. 97 - 98 - To compile it as a module, choose M here. If unsure, say N. 99 - 100 90 config IP6_NF_MATCH_OWNER 101 91 tristate "Owner match support" 102 92 depends on IP6_NF_IPTABLES ··· 105 115 106 116 To compile it as a module, choose M here. If unsure, say N. 107 117 108 - config IP6_NF_MATCH_AHESP 109 - tristate "AH/ESP match support" 118 + config IP6_NF_MATCH_AH 119 + tristate "AH match support" 110 120 depends on IP6_NF_IPTABLES 111 121 help 112 - This module allows one to match AH and ESP packets. 122 + This module allows one to match AH packets. 113 123 114 124 To compile it as a module, choose M here. If unsure, say N. 115 125
+1 -2
net/ipv6/netfilter/Makefile
··· 8 8 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o ip6t_dst.o 9 9 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o 10 10 obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o 11 - obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o 11 + obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o 12 12 obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o 13 - obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o 14 13 obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o 15 14 obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o 16 15 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
-115
net/ipv6/netfilter/ip6t_esp.c
··· 1 - /* Kernel module to match ESP parameters. */ 2 - /* (C) 2001-2002 Andras Kis-Szabo <kisza@sch.bme.hu> 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License version 2 as 6 - * published by the Free Software Foundation. 7 - */ 8 - 9 - 10 - #include <linux/module.h> 11 - #include <linux/skbuff.h> 12 - #include <linux/ip.h> 13 - #include <linux/ipv6.h> 14 - #include <linux/types.h> 15 - #include <net/checksum.h> 16 - #include <net/ipv6.h> 17 - 18 - #include <linux/netfilter_ipv6/ip6_tables.h> 19 - #include <linux/netfilter_ipv6/ip6t_esp.h> 20 - 21 - MODULE_LICENSE("GPL"); 22 - MODULE_DESCRIPTION("IPv6 ESP match"); 23 - MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 24 - 25 - #if 0 26 - #define DEBUGP printk 27 - #else 28 - #define DEBUGP(format, args...) 29 - #endif 30 - 31 - /* Returns 1 if the spi is matched by the range, 0 otherwise */ 32 - static inline int 33 - spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert) 34 - { 35 - int r=0; 36 - DEBUGP("esp spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', 37 - min,spi,max); 38 - r=(spi >= min && spi <= max) ^ invert; 39 - DEBUGP(" result %s\n",r? "PASS\n" : "FAILED\n"); 40 - return r; 41 - } 42 - 43 - static int 44 - match(const struct sk_buff *skb, 45 - const struct net_device *in, 46 - const struct net_device *out, 47 - const struct xt_match *match, 48 - const void *matchinfo, 49 - int offset, 50 - unsigned int protoff, 51 - int *hotdrop) 52 - { 53 - struct ip_esp_hdr _esp, *eh; 54 - const struct ip6t_esp *espinfo = matchinfo; 55 - unsigned int ptr; 56 - 57 - /* Make sure this isn't an evil packet */ 58 - /*DEBUGP("ipv6_esp entered \n");*/ 59 - 60 - if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP, NULL) < 0) 61 - return 0; 62 - 63 - eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp); 64 - if (eh == NULL) { 65 - *hotdrop = 1; 66 - return 0; 67 - } 68 - 69 - DEBUGP("IPv6 ESP SPI %u %08X\n", ntohl(eh->spi), ntohl(eh->spi)); 70 - 71 - return (eh != NULL) 72 - && spi_match(espinfo->spis[0], espinfo->spis[1], 73 - ntohl(eh->spi), 74 - !!(espinfo->invflags & IP6T_ESP_INV_SPI)); 75 - } 76 - 77 - /* Called when user tries to insert an entry of this type. */ 78 - static int 79 - checkentry(const char *tablename, 80 - const void *ip, 81 - const struct xt_match *match, 82 - void *matchinfo, 83 - unsigned int matchinfosize, 84 - unsigned int hook_mask) 85 - { 86 - const struct ip6t_esp *espinfo = matchinfo; 87 - 88 - if (espinfo->invflags & ~IP6T_ESP_INV_MASK) { 89 - DEBUGP("ip6t_esp: unknown flags %X\n", 90 - espinfo->invflags); 91 - return 0; 92 - } 93 - return 1; 94 - } 95 - 96 - static struct ip6t_match esp_match = { 97 - .name = "esp", 98 - .match = match, 99 - .matchsize = sizeof(struct ip6t_esp), 100 - .checkentry = checkentry, 101 - .me = THIS_MODULE, 102 - }; 103 - 104 - static int __init ip6t_esp_init(void) 105 - { 106 - return ip6t_register_match(&esp_match); 107 - } 108 - 109 - static void __exit ip6t_esp_fini(void) 110 - { 111 - ip6t_unregister_match(&esp_match); 112 - } 113 - 114 - module_init(ip6t_esp_init); 115 - module_exit(ip6t_esp_fini);
-125
net/ipv6/netfilter/ip6t_multiport.c
··· 1 - /* Kernel module to match one of a list of TCP/UDP ports: ports are in 2 - the same place so we can treat them as equal. */ 3 - 4 - /* (C) 1999-2001 Paul `Rusty' Russell 5 - * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 - */ 11 - 12 - #include <linux/module.h> 13 - #include <linux/types.h> 14 - #include <linux/udp.h> 15 - #include <linux/skbuff.h> 16 - #include <linux/in.h> 17 - 18 - #include <linux/netfilter_ipv6/ip6t_multiport.h> 19 - #include <linux/netfilter_ipv6/ip6_tables.h> 20 - 21 - MODULE_LICENSE("GPL"); 22 - MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 23 - MODULE_DESCRIPTION("ip6tables match for multiple ports"); 24 - 25 - #if 0 26 - #define duprintf(format, args...) printk(format , ## args) 27 - #else 28 - #define duprintf(format, args...) 29 - #endif 30 - 31 - /* Returns 1 if the port is matched by the test, 0 otherwise. */ 32 - static inline int 33 - ports_match(const u_int16_t *portlist, enum ip6t_multiport_flags flags, 34 - u_int8_t count, u_int16_t src, u_int16_t dst) 35 - { 36 - unsigned int i; 37 - for (i=0; i<count; i++) { 38 - if (flags != IP6T_MULTIPORT_DESTINATION 39 - && portlist[i] == src) 40 - return 1; 41 - 42 - if (flags != IP6T_MULTIPORT_SOURCE 43 - && portlist[i] == dst) 44 - return 1; 45 - } 46 - 47 - return 0; 48 - } 49 - 50 - static int 51 - match(const struct sk_buff *skb, 52 - const struct net_device *in, 53 - const struct net_device *out, 54 - const struct xt_match *match, 55 - const void *matchinfo, 56 - int offset, 57 - unsigned int protoff, 58 - int *hotdrop) 59 - { 60 - u16 _ports[2], *pptr; 61 - const struct ip6t_multiport *multiinfo = matchinfo; 62 - 63 - /* Must not be a fragment. */ 64 - if (offset) 65 - return 0; 66 - 67 - /* Must be big enough to read ports (both UDP and TCP have 68 - them at the start). */ 69 - pptr = skb_header_pointer(skb, protoff, sizeof(_ports), &_ports[0]); 70 - if (pptr == NULL) { 71 - /* We've been asked to examine this packet, and we 72 - * can't. Hence, no choice but to drop. 73 - */ 74 - duprintf("ip6t_multiport:" 75 - " Dropping evil offset=0 tinygram.\n"); 76 - *hotdrop = 1; 77 - return 0; 78 - } 79 - 80 - return ports_match(multiinfo->ports, 81 - multiinfo->flags, multiinfo->count, 82 - ntohs(pptr[0]), ntohs(pptr[1])); 83 - } 84 - 85 - /* Called when user tries to insert an entry of this type. */ 86 - static int 87 - checkentry(const char *tablename, 88 - const void *info, 89 - const struct xt_match *match, 90 - void *matchinfo, 91 - unsigned int matchsize, 92 - unsigned int hook_mask) 93 - { 94 - const struct ip6t_ip6 *ip = info; 95 - const struct ip6t_multiport *multiinfo = matchinfo; 96 - 97 - /* Must specify proto == TCP/UDP, no unknown flags or bad count */ 98 - return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP) 99 - && !(ip->invflags & IP6T_INV_PROTO) 100 - && (multiinfo->flags == IP6T_MULTIPORT_SOURCE 101 - || multiinfo->flags == IP6T_MULTIPORT_DESTINATION 102 - || multiinfo->flags == IP6T_MULTIPORT_EITHER) 103 - && multiinfo->count <= IP6T_MULTI_PORTS; 104 - } 105 - 106 - static struct ip6t_match multiport_match = { 107 - .name = "multiport", 108 - .match = match, 109 - .matchsize = sizeof(struct ip6t_multiport), 110 - .checkentry = checkentry, 111 - .me = THIS_MODULE, 112 - }; 113 - 114 - static int __init ip6t_multiport_init(void) 115 - { 116 - return ip6t_register_match(&multiport_match); 117 - } 118 - 119 - static void __exit ip6t_multiport_fini(void) 120 - { 121 - ip6t_unregister_match(&multiport_match); 122 - } 123 - 124 - module_init(ip6t_multiport_init); 125 - module_exit(ip6t_multiport_fini);
+6 -5
net/ipv6/xfrm6_input.c
··· 32 32 { 33 33 int err; 34 34 u32 seq; 35 - struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; 35 + struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; 36 36 struct xfrm_state *x; 37 37 int xfrm_nr = 0; 38 38 int decaps = 0; ··· 65 65 if (xfrm_state_check_expire(x)) 66 66 goto drop_unlock; 67 67 68 - nexthdr = x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb); 68 + nexthdr = x->type->input(x, skb); 69 69 if (nexthdr <= 0) 70 70 goto drop_unlock; 71 71 ··· 79 79 80 80 spin_unlock(&x->lock); 81 81 82 - xfrm_vec[xfrm_nr++].xvec = x; 82 + xfrm_vec[xfrm_nr++] = x; 83 83 84 84 if (x->props.mode) { /* XXX */ 85 85 if (nexthdr != IPPROTO_IPV6) ··· 118 118 if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) 119 119 goto drop; 120 120 121 - memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state)); 121 + memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec, 122 + xfrm_nr * sizeof(xfrm_vec[0])); 122 123 skb->sp->len += xfrm_nr; 123 124 skb->ip_summed = CHECKSUM_NONE; 124 125 ··· 150 149 xfrm_state_put(x); 151 150 drop: 152 151 while (--xfrm_nr >= 0) 153 - xfrm_state_put(xfrm_vec[xfrm_nr].xvec); 152 + xfrm_state_put(xfrm_vec[xfrm_nr]); 154 153 kfree_skb(skb); 155 154 return -1; 156 155 }
+1 -1
net/ipv6/xfrm6_tunnel.c
··· 351 351 return 0; 352 352 } 353 353 354 - static int xfrm6_tunnel_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) 354 + static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) 355 355 { 356 356 return 0; 357 357 }
+19
net/netfilter/Kconfig
··· 231 231 If you want to compile it as a module, say M here and read 232 232 <file:Documentation/modules.txt>. If unsure, say `N'. 233 233 234 + config NETFILTER_XT_MATCH_ESP 235 + tristate '"ESP" match support' 236 + depends on NETFILTER_XTABLES 237 + help 238 + This match extension allows you to match a range of SPIs 239 + inside ESP header of IPSec packets. 240 + 241 + To compile it as a module, choose M here. If unsure, say N. 242 + 234 243 config NETFILTER_XT_MATCH_HELPER 235 244 tristate '"helper" match support' 236 245 depends on NETFILTER_XTABLES ··· 295 286 Policy matching allows you to match packets based on the 296 287 IPsec policy that was used during decapsulation/will 297 288 be used during encapsulation. 289 + 290 + To compile it as a module, choose M here. If unsure, say N. 291 + 292 + config NETFILTER_XT_MATCH_MULTIPORT 293 + tristate "Multiple port match support" 294 + depends on NETFILTER_XTABLES 295 + help 296 + Multiport matching allows you to match TCP or UDP packets based on 297 + a series of source or destination ports: normally a rule can only 298 + match a single range of ports. 298 299 299 300 To compile it as a module, choose M here. If unsure, say N. 300 301
+2
net/netfilter/Makefile
··· 35 35 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o 36 36 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o 37 37 obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o 38 + obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o 38 39 obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o 39 40 obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o 40 41 obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o 41 42 obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o 42 43 obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o 44 + obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o 43 45 obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o 44 46 obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o 45 47 obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
+3 -3
net/netfilter/nf_conntrack_netlink.c
··· 1022 1022 return err; 1023 1023 } 1024 1024 1025 - #if defined(CONFIG_IP_NF_CONNTRACK_MARK) 1025 + #if defined(CONFIG_NF_CONNTRACK_MARK) 1026 1026 if (cda[CTA_MARK-1]) 1027 1027 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); 1028 1028 #endif ··· 1062 1062 return err; 1063 1063 } 1064 1064 1065 - #if defined(CONFIG_IP_NF_CONNTRACK_MARK) 1065 + #if defined(CONFIG_NF_CONNTRACK_MARK) 1066 1066 if (cda[CTA_MARK-1]) 1067 1067 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); 1068 1068 #endif ··· 1687 1687 printk("ctnetlink: unregistering from nfnetlink.\n"); 1688 1688 1689 1689 #ifdef CONFIG_NF_CONNTRACK_EVENTS 1690 - nf_conntrack_unregister_notifier(&ctnl_notifier_exp); 1690 + nf_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); 1691 1691 nf_conntrack_unregister_notifier(&ctnl_notifier); 1692 1692 #endif 1693 1693
+113
net/netfilter/x_tables.c
··· 38 38 struct list_head match; 39 39 struct list_head target; 40 40 struct list_head tables; 41 + struct mutex compat_mutex; 41 42 }; 42 43 43 44 static struct xt_af *xt; ··· 273 272 } 274 273 EXPORT_SYMBOL_GPL(xt_check_match); 275 274 275 + #ifdef CONFIG_COMPAT 276 + int xt_compat_match(void *match, void **dstptr, int *size, int convert) 277 + { 278 + struct xt_match *m; 279 + struct compat_xt_entry_match *pcompat_m; 280 + struct xt_entry_match *pm; 281 + u_int16_t msize; 282 + int off, ret; 283 + 284 + ret = 0; 285 + m = ((struct xt_entry_match *)match)->u.kernel.match; 286 + off = XT_ALIGN(m->matchsize) - COMPAT_XT_ALIGN(m->matchsize); 287 + switch (convert) { 288 + case COMPAT_TO_USER: 289 + pm = (struct xt_entry_match *)match; 290 + msize = pm->u.user.match_size; 291 + if (__copy_to_user(*dstptr, pm, msize)) { 292 + ret = -EFAULT; 293 + break; 294 + } 295 + msize -= off; 296 + if (put_user(msize, (u_int16_t *)*dstptr)) 297 + ret = -EFAULT; 298 + *size -= off; 299 + *dstptr += msize; 300 + break; 301 + case COMPAT_FROM_USER: 302 + pcompat_m = (struct compat_xt_entry_match *)match; 303 + pm = (struct xt_entry_match *)*dstptr; 304 + msize = pcompat_m->u.user.match_size; 305 + memcpy(pm, pcompat_m, msize); 306 + msize += off; 307 + pm->u.user.match_size = msize; 308 + *size += off; 309 + *dstptr += msize; 310 + break; 311 + case COMPAT_CALC_SIZE: 312 + *size += off; 313 + break; 314 + default: 315 + ret = -ENOPROTOOPT; 316 + break; 317 + } 318 + return ret; 319 + } 320 + EXPORT_SYMBOL_GPL(xt_compat_match); 321 + #endif 322 + 276 323 int xt_check_target(const struct xt_target *target, unsigned short family, 277 324 unsigned int size, const char *table, unsigned int hook_mask, 278 325 unsigned short proto, int inv_proto) ··· 349 300 return 0; 350 301 } 351 302 EXPORT_SYMBOL_GPL(xt_check_target); 303 + 304 + #ifdef CONFIG_COMPAT 305 + int xt_compat_target(void *target, void **dstptr, int *size, int convert) 306 + { 307 + struct xt_target *t; 308 + struct compat_xt_entry_target *pcompat; 309 + struct xt_entry_target *pt; 310 + u_int16_t tsize; 311 + int off, ret; 312 + 313 + ret = 0; 314 + t = ((struct xt_entry_target *)target)->u.kernel.target; 315 + off = XT_ALIGN(t->targetsize) - COMPAT_XT_ALIGN(t->targetsize); 316 + switch (convert) { 317 + case COMPAT_TO_USER: 318 + pt = (struct xt_entry_target *)target; 319 + tsize = pt->u.user.target_size; 320 + if (__copy_to_user(*dstptr, pt, tsize)) { 321 + ret = -EFAULT; 322 + break; 323 + } 324 + tsize -= off; 325 + if (put_user(tsize, (u_int16_t *)*dstptr)) 326 + ret = -EFAULT; 327 + *size -= off; 328 + *dstptr += tsize; 329 + break; 330 + case COMPAT_FROM_USER: 331 + pcompat = (struct compat_xt_entry_target *)target; 332 + pt = (struct xt_entry_target *)*dstptr; 333 + tsize = pcompat->u.user.target_size; 334 + memcpy(pt, pcompat, tsize); 335 + tsize += off; 336 + pt->u.user.target_size = tsize; 337 + *size += off; 338 + *dstptr += tsize; 339 + break; 340 + case COMPAT_CALC_SIZE: 341 + *size += off; 342 + break; 343 + default: 344 + ret = -ENOPROTOOPT; 345 + break; 346 + } 347 + return ret; 348 + } 349 + EXPORT_SYMBOL_GPL(xt_compat_target); 350 + #endif 352 351 353 352 struct xt_table_info *xt_alloc_table_info(unsigned int size) 354 353 { ··· 468 371 } 469 372 EXPORT_SYMBOL_GPL(xt_table_unlock); 470 373 374 + #ifdef CONFIG_COMPAT 375 + void xt_compat_lock(int af) 376 + { 377 + mutex_lock(&xt[af].compat_mutex); 378 + } 379 + EXPORT_SYMBOL_GPL(xt_compat_lock); 380 + 381 + void xt_compat_unlock(int af) 382 + { 383 + mutex_unlock(&xt[af].compat_mutex); 384 + } 385 + EXPORT_SYMBOL_GPL(xt_compat_unlock); 386 + #endif 471 387 472 388 struct xt_table_info * 473 389 xt_replace_table(struct xt_table *table, ··· 781 671 782 672 for (i = 0; i < NPROTO; i++) { 783 673 mutex_init(&xt[i].mutex); 674 + #ifdef CONFIG_COMPAT 675 + mutex_init(&xt[i].compat_mutex); 676 + #endif 784 677 INIT_LIST_HEAD(&xt[i].target); 785 678 INIT_LIST_HEAD(&xt[i].match); 786 679 INIT_LIST_HEAD(&xt[i].tables);
+314
net/netfilter/xt_multiport.c
··· 1 + /* Kernel module to match one of a list of TCP/UDP ports: ports are in 2 + the same place so we can treat them as equal. */ 3 + 4 + /* (C) 1999-2001 Paul `Rusty' Russell 5 + * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #include <linux/module.h> 13 + #include <linux/types.h> 14 + #include <linux/udp.h> 15 + #include <linux/skbuff.h> 16 + #include <linux/in.h> 17 + 18 + #include <linux/netfilter/xt_multiport.h> 19 + #include <linux/netfilter/x_tables.h> 20 + #include <linux/netfilter_ipv4/ip_tables.h> 21 + #include <linux/netfilter_ipv6/ip6_tables.h> 22 + 23 + MODULE_LICENSE("GPL"); 24 + MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 25 + MODULE_DESCRIPTION("x_tables multiple port match module"); 26 + MODULE_ALIAS("ipt_multiport"); 27 + MODULE_ALIAS("ip6t_multiport"); 28 + 29 + #if 0 30 + #define duprintf(format, args...) printk(format , ## args) 31 + #else 32 + #define duprintf(format, args...) 33 + #endif 34 + 35 + /* Returns 1 if the port is matched by the test, 0 otherwise. */ 36 + static inline int 37 + ports_match(const u_int16_t *portlist, enum xt_multiport_flags flags, 38 + u_int8_t count, u_int16_t src, u_int16_t dst) 39 + { 40 + unsigned int i; 41 + for (i = 0; i < count; i++) { 42 + if (flags != XT_MULTIPORT_DESTINATION && portlist[i] == src) 43 + return 1; 44 + 45 + if (flags != XT_MULTIPORT_SOURCE && portlist[i] == dst) 46 + return 1; 47 + } 48 + 49 + return 0; 50 + } 51 + 52 + /* Returns 1 if the port is matched by the test, 0 otherwise. */ 53 + static inline int 54 + ports_match_v1(const struct xt_multiport_v1 *minfo, 55 + u_int16_t src, u_int16_t dst) 56 + { 57 + unsigned int i; 58 + u_int16_t s, e; 59 + 60 + for (i = 0; i < minfo->count; i++) { 61 + s = minfo->ports[i]; 62 + 63 + if (minfo->pflags[i]) { 64 + /* range port matching */ 65 + e = minfo->ports[++i]; 66 + duprintf("src or dst matches with %d-%d?\n", s, e); 67 + 68 + if (minfo->flags == XT_MULTIPORT_SOURCE 69 + && src >= s && src <= e) 70 + return 1 ^ minfo->invert; 71 + if (minfo->flags == XT_MULTIPORT_DESTINATION 72 + && dst >= s && dst <= e) 73 + return 1 ^ minfo->invert; 74 + if (minfo->flags == XT_MULTIPORT_EITHER 75 + && ((dst >= s && dst <= e) 76 + || (src >= s && src <= e))) 77 + return 1 ^ minfo->invert; 78 + } else { 79 + /* exact port matching */ 80 + duprintf("src or dst matches with %d?\n", s); 81 + 82 + if (minfo->flags == XT_MULTIPORT_SOURCE 83 + && src == s) 84 + return 1 ^ minfo->invert; 85 + if (minfo->flags == XT_MULTIPORT_DESTINATION 86 + && dst == s) 87 + return 1 ^ minfo->invert; 88 + if (minfo->flags == XT_MULTIPORT_EITHER 89 + && (src == s || dst == s)) 90 + return 1 ^ minfo->invert; 91 + } 92 + } 93 + 94 + return minfo->invert; 95 + } 96 + 97 + static int 98 + match(const struct sk_buff *skb, 99 + const struct net_device *in, 100 + const struct net_device *out, 101 + const struct xt_match *match, 102 + const void *matchinfo, 103 + int offset, 104 + unsigned int protoff, 105 + int *hotdrop) 106 + { 107 + u16 _ports[2], *pptr; 108 + const struct xt_multiport *multiinfo = matchinfo; 109 + 110 + if (offset) 111 + return 0; 112 + 113 + pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports); 114 + if (pptr == NULL) { 115 + /* We've been asked to examine this packet, and we 116 + * can't. Hence, no choice but to drop. 117 + */ 118 + duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n"); 119 + *hotdrop = 1; 120 + return 0; 121 + } 122 + 123 + return ports_match(multiinfo->ports, 124 + multiinfo->flags, multiinfo->count, 125 + ntohs(pptr[0]), ntohs(pptr[1])); 126 + } 127 + 128 + static int 129 + match_v1(const struct sk_buff *skb, 130 + const struct net_device *in, 131 + const struct net_device *out, 132 + const struct xt_match *match, 133 + const void *matchinfo, 134 + int offset, 135 + unsigned int protoff, 136 + int *hotdrop) 137 + { 138 + u16 _ports[2], *pptr; 139 + const struct xt_multiport_v1 *multiinfo = matchinfo; 140 + 141 + if (offset) 142 + return 0; 143 + 144 + pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports); 145 + if (pptr == NULL) { 146 + /* We've been asked to examine this packet, and we 147 + * can't. Hence, no choice but to drop. 148 + */ 149 + duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n"); 150 + *hotdrop = 1; 151 + return 0; 152 + } 153 + 154 + return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1])); 155 + } 156 + 157 + static inline int 158 + check(u_int16_t proto, 159 + u_int8_t ip_invflags, 160 + u_int8_t match_flags, 161 + u_int8_t count) 162 + { 163 + /* Must specify proto == TCP/UDP, no unknown flags or bad count */ 164 + return (proto == IPPROTO_TCP || proto == IPPROTO_UDP) 165 + && !(ip_invflags & XT_INV_PROTO) 166 + && (match_flags == XT_MULTIPORT_SOURCE 167 + || match_flags == XT_MULTIPORT_DESTINATION 168 + || match_flags == XT_MULTIPORT_EITHER) 169 + && count <= XT_MULTI_PORTS; 170 + } 171 + 172 + /* Called when user tries to insert an entry of this type. */ 173 + static int 174 + checkentry(const char *tablename, 175 + const void *info, 176 + const struct xt_match *match, 177 + void *matchinfo, 178 + unsigned int matchsize, 179 + unsigned int hook_mask) 180 + { 181 + const struct ipt_ip *ip = info; 182 + const struct xt_multiport *multiinfo = matchinfo; 183 + 184 + return check(ip->proto, ip->invflags, multiinfo->flags, 185 + multiinfo->count); 186 + } 187 + 188 + static int 189 + checkentry_v1(const char *tablename, 190 + const void *info, 191 + const struct xt_match *match, 192 + void *matchinfo, 193 + unsigned int matchsize, 194 + unsigned int hook_mask) 195 + { 196 + const struct ipt_ip *ip = info; 197 + const struct xt_multiport_v1 *multiinfo = matchinfo; 198 + 199 + return check(ip->proto, ip->invflags, multiinfo->flags, 200 + multiinfo->count); 201 + } 202 + 203 + static int 204 + checkentry6(const char *tablename, 205 + const void *info, 206 + const struct xt_match *match, 207 + void *matchinfo, 208 + unsigned int matchsize, 209 + unsigned int hook_mask) 210 + { 211 + const struct ip6t_ip6 *ip = info; 212 + const struct xt_multiport *multiinfo = matchinfo; 213 + 214 + return check(ip->proto, ip->invflags, multiinfo->flags, 215 + multiinfo->count); 216 + } 217 + 218 + static int 219 + checkentry6_v1(const char *tablename, 220 + const void *info, 221 + const struct xt_match *match, 222 + void *matchinfo, 223 + unsigned int matchsize, 224 + unsigned int hook_mask) 225 + { 226 + const struct ip6t_ip6 *ip = info; 227 + const struct xt_multiport_v1 *multiinfo = matchinfo; 228 + 229 + return check(ip->proto, ip->invflags, multiinfo->flags, 230 + multiinfo->count); 231 + } 232 + 233 + static struct xt_match multiport_match = { 234 + .name = "multiport", 235 + .revision = 0, 236 + .matchsize = sizeof(struct xt_multiport), 237 + .match = &match, 238 + .checkentry = &checkentry, 239 + .family = AF_INET, 240 + .me = THIS_MODULE, 241 + }; 242 + 243 + static struct xt_match multiport_match_v1 = { 244 + .name = "multiport", 245 + .revision = 1, 246 + .matchsize = sizeof(struct xt_multiport_v1), 247 + .match = &match_v1, 248 + .checkentry = &checkentry_v1, 249 + .family = AF_INET, 250 + .me = THIS_MODULE, 251 + }; 252 + 253 + static struct xt_match multiport6_match = { 254 + .name = "multiport", 255 + .revision = 0, 256 + .matchsize = sizeof(struct xt_multiport), 257 + .match = &match, 258 + .checkentry = &checkentry6, 259 + .family = AF_INET6, 260 + .me = THIS_MODULE, 261 + }; 262 + 263 + static struct xt_match multiport6_match_v1 = { 264 + .name = "multiport", 265 + .revision = 1, 266 + .matchsize = sizeof(struct xt_multiport_v1), 267 + .match = &match_v1, 268 + .checkentry = &checkentry6_v1, 269 + .family = AF_INET6, 270 + .me = THIS_MODULE, 271 + }; 272 + 273 + static int __init xt_multiport_init(void) 274 + { 275 + int ret; 276 + 277 + ret = xt_register_match(&multiport_match); 278 + if (ret) 279 + goto out; 280 + 281 + ret = xt_register_match(&multiport_match_v1); 282 + if (ret) 283 + goto out_unreg_multi_v0; 284 + 285 + ret = xt_register_match(&multiport6_match); 286 + if (ret) 287 + goto out_unreg_multi_v1; 288 + 289 + ret = xt_register_match(&multiport6_match_v1); 290 + if (ret) 291 + goto out_unreg_multi6_v0; 292 + 293 + return ret; 294 + 295 + out_unreg_multi6_v0: 296 + xt_unregister_match(&multiport6_match); 297 + out_unreg_multi_v1: 298 + xt_unregister_match(&multiport_match_v1); 299 + out_unreg_multi_v0: 300 + xt_unregister_match(&multiport_match); 301 + out: 302 + return ret; 303 + } 304 + 305 + static void __exit xt_multiport_fini(void) 306 + { 307 + xt_unregister_match(&multiport_match); 308 + xt_unregister_match(&multiport_match_v1); 309 + xt_unregister_match(&multiport6_match); 310 + xt_unregister_match(&multiport6_match_v1); 311 + } 312 + 313 + module_init(xt_multiport_init); 314 + module_exit(xt_multiport_fini);
+1 -1
net/netfilter/xt_policy.c
··· 71 71 return 0; 72 72 e = &info->pol[pos]; 73 73 74 - if (match_xfrm_state(sp->x[i].xvec, e, family)) { 74 + if (match_xfrm_state(sp->xvec[i], e, family)) { 75 75 if (!strict) 76 76 return 1; 77 77 } else if (strict)
+3 -4
net/socket.c
··· 1418 1418 newfd = sock_alloc_fd(&newfile); 1419 1419 if (unlikely(newfd < 0)) { 1420 1420 err = newfd; 1421 - goto out_release; 1421 + sock_release(newsock); 1422 + goto out_put; 1422 1423 } 1423 1424 1424 1425 err = sock_attach_fd(newsock, newfile); ··· 1456 1455 out: 1457 1456 return err; 1458 1457 out_fd: 1459 - put_filp(newfile); 1458 + fput(newfile); 1460 1459 put_unused_fd(newfd); 1461 - out_release: 1462 - sock_release(newsock); 1463 1460 goto out_put; 1464 1461 } 1465 1462
+2 -2
net/xfrm/xfrm_input.c
··· 18 18 { 19 19 int i; 20 20 for (i = 0; i < sp->len; i++) 21 - xfrm_state_put(sp->x[i].xvec); 21 + xfrm_state_put(sp->xvec[i]); 22 22 kmem_cache_free(secpath_cachep, sp); 23 23 } 24 24 EXPORT_SYMBOL(__secpath_destroy); ··· 37 37 38 38 memcpy(sp, src, sizeof(*sp)); 39 39 for (i = 0; i < sp->len; i++) 40 - xfrm_state_hold(sp->x[i].xvec); 40 + xfrm_state_hold(sp->xvec[i]); 41 41 } 42 42 atomic_set(&sp->refcnt, 1); 43 43 return sp;
+5 -5
net/xfrm/xfrm_policy.c
··· 943 943 } else 944 944 start = -1; 945 945 for (; idx < sp->len; idx++) { 946 - if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family)) 946 + if (xfrm_state_ok(tmpl, sp->xvec[idx], family)) 947 947 return ++idx; 948 - if (sp->x[idx].xvec->props.mode) 948 + if (sp->xvec[idx]->props.mode) 949 949 break; 950 950 } 951 951 return start; ··· 968 968 static inline int secpath_has_tunnel(struct sec_path *sp, int k) 969 969 { 970 970 for (; k < sp->len; k++) { 971 - if (sp->x[k].xvec->props.mode) 971 + if (sp->xvec[k]->props.mode) 972 972 return 1; 973 973 } 974 974 ··· 994 994 int i; 995 995 996 996 for (i=skb->sp->len-1; i>=0; i--) { 997 - struct sec_decap_state *xvec = &(skb->sp->x[i]); 998 - if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) 997 + struct xfrm_state *x = skb->sp->xvec[i]; 998 + if (!xfrm_selector_match(&x->sel, &fl, family)) 999 999 return 0; 1000 1000 } 1001 1001 }