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

+63 -27
+16 -5
include/linux/netfilter.h
··· 184 184 struct sk_buff **pskb, 185 185 struct net_device *indev, 186 186 struct net_device *outdev, 187 - int (*okfn)(struct sk_buff *), int thresh) 187 + int (*okfn)(struct sk_buff *), int thresh, 188 + int cond) 188 189 { 190 + if (!cond) 191 + return 1; 189 192 #ifndef CONFIG_NETFILTER_DEBUG 190 193 if (list_empty(&nf_hooks[pf][hook])) 191 194 return 1; ··· 200 197 struct net_device *indev, struct net_device *outdev, 201 198 int (*okfn)(struct sk_buff *)) 202 199 { 203 - return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN); 200 + return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN, 1); 204 201 } 205 202 206 203 /* Activate hook; either okfn or kfree_skb called, unless a hook ··· 227 224 228 225 #define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \ 229 226 ({int __ret; \ 230 - if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1)\ 227 + if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh, 1)) == 1)\ 228 + __ret = (okfn)(skb); \ 229 + __ret;}) 230 + 231 + #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) \ 232 + ({int __ret; \ 233 + if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, INT_MIN, cond)) == 1)\ 231 234 __ret = (okfn)(skb); \ 232 235 __ret;}) 233 236 ··· 304 295 305 296 #else /* !CONFIG_NETFILTER */ 306 297 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) 298 + #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb) 307 299 static inline int nf_hook_thresh(int pf, unsigned int hook, 308 300 struct sk_buff **pskb, 309 301 struct net_device *indev, 310 302 struct net_device *outdev, 311 - int (*okfn)(struct sk_buff *), int thresh) 303 + int (*okfn)(struct sk_buff *), int thresh, 304 + int cond) 312 305 { 313 306 return okfn(*pskb); 314 307 } ··· 318 307 struct net_device *indev, struct net_device *outdev, 319 308 int (*okfn)(struct sk_buff *)) 320 309 { 321 - return okfn(*pskb); 310 + return 1; 322 311 } 323 312 static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} 324 313 struct flowi;
+1
include/net/ip.h
··· 41 41 #define IPSKB_XFRM_TUNNEL_SIZE 2 42 42 #define IPSKB_XFRM_TRANSFORMED 4 43 43 #define IPSKB_FRAG_COMPLETE 8 44 + #define IPSKB_REROUTED 16 44 45 }; 45 46 46 47 struct ipcm_cookie
-1
include/net/xfrm.h
··· 866 866 extern int xfrm_init_state(struct xfrm_state *x); 867 867 extern int xfrm4_rcv(struct sk_buff *skb); 868 868 extern int xfrm4_output(struct sk_buff *skb); 869 - extern int xfrm4_output_finish(struct sk_buff *skb); 870 869 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); 871 870 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); 872 871 extern int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi);
+2 -1
net/ipv4/ip_gre.c
··· 830 830 skb->h.raw = skb->nh.raw; 831 831 skb->nh.raw = skb_push(skb, gre_hlen); 832 832 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 833 - IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED); 833 + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | 834 + IPSKB_REROUTED); 834 835 dst_release(skb->dst); 835 836 skb->dst = &rt->u.dst; 836 837
+10 -6
net/ipv4/ip_output.c
··· 207 207 { 208 208 #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) 209 209 /* Policy lookup after SNAT yielded a new policy */ 210 - if (skb->dst->xfrm != NULL) 211 - return xfrm4_output_finish(skb); 210 + if (skb->dst->xfrm != NULL) { 211 + IPCB(skb)->flags |= IPSKB_REROUTED; 212 + return dst_output(skb); 213 + } 212 214 #endif 213 215 if (skb->len > dst_mtu(skb->dst) && 214 216 !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size)) ··· 273 271 newskb->dev, ip_dev_loopback_xmit); 274 272 } 275 273 276 - return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, 277 - ip_finish_output); 274 + return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev, 275 + ip_finish_output, 276 + !(IPCB(skb)->flags & IPSKB_REROUTED)); 278 277 } 279 278 280 279 int ip_output(struct sk_buff *skb) ··· 287 284 skb->dev = dev; 288 285 skb->protocol = htons(ETH_P_IP); 289 286 290 - return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, 291 - ip_finish_output); 287 + return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, 288 + ip_finish_output, 289 + !(IPCB(skb)->flags & IPSKB_REROUTED)); 292 290 } 293 291 294 292 int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
+2 -1
net/ipv4/ipip.c
··· 622 622 skb->h.raw = skb->nh.raw; 623 623 skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); 624 624 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 625 - IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED); 625 + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | 626 + IPSKB_REROUTED); 626 627 dst_release(skb->dst); 627 628 skb->dst = &rt->u.dst; 628 629
-5
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
··· 529 529 goto cleanup_localinops; 530 530 } 531 531 #endif 532 - 533 - /* For use by REJECT target */ 534 - ip_ct_attach = __nf_conntrack_attach; 535 - 536 532 return ret; 537 533 538 534 cleanup: 539 535 synchronize_net(); 540 - ip_ct_attach = NULL; 541 536 #ifdef CONFIG_SYSCTL 542 537 unregister_sysctl_table(nf_ct_ipv4_sysctl_header); 543 538 cleanup_localinops:
+10 -3
net/ipv4/xfrm4_output.c
··· 152 152 goto out_exit; 153 153 } 154 154 155 - int xfrm4_output_finish(struct sk_buff *skb) 155 + static int xfrm4_output_finish(struct sk_buff *skb) 156 156 { 157 157 int err; 158 158 159 + #ifdef CONFIG_NETFILTER 160 + if (!skb->dst->xfrm) { 161 + IPCB(skb)->flags |= IPSKB_REROUTED; 162 + return dst_output(skb); 163 + } 164 + #endif 159 165 while (likely((err = xfrm4_output_one(skb)) == 0)) { 160 166 nf_reset(skb); 161 167 ··· 184 178 185 179 int xfrm4_output(struct sk_buff *skb) 186 180 { 187 - return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, 188 - xfrm4_output_finish); 181 + return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev, 182 + xfrm4_output_finish, 183 + !(IPCB(skb)->flags & IPSKB_REROUTED)); 189 184 }
+6
net/ipv6/icmp.c
··· 42 42 #include <linux/net.h> 43 43 #include <linux/skbuff.h> 44 44 #include <linux/init.h> 45 + #include <linux/netfilter.h> 45 46 46 47 #ifdef CONFIG_SYSCTL 47 48 #include <linux/sysctl.h> ··· 256 255 struct icmpv6_msg { 257 256 struct sk_buff *skb; 258 257 int offset; 258 + uint8_t type; 259 259 }; 260 260 261 261 static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) ··· 268 266 csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset, 269 267 to, len, csum); 270 268 skb->csum = csum_block_add(skb->csum, csum, odd); 269 + if (!(msg->type & ICMPV6_INFOMSG_MASK)) 270 + nf_ct_attach(skb, org_skb); 271 271 return 0; 272 272 } 273 273 ··· 407 403 408 404 msg.skb = skb; 409 405 msg.offset = skb->nh.raw - skb->data; 406 + msg.type = type; 410 407 411 408 len = skb->len - msg.offset; 412 409 len = min_t(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr) -sizeof(struct icmp6hdr)); ··· 505 500 506 501 msg.skb = skb; 507 502 msg.offset = 0; 503 + msg.type = ICMPV6_ECHO_REPLY; 508 504 509 505 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), 510 506 sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
+2
net/ipv6/netfilter/ip6t_REJECT.c
··· 160 160 csum_partial((char *)tcph, 161 161 sizeof(struct tcphdr), 0)); 162 162 163 + nf_ct_attach(nskb, oldskb); 164 + 163 165 NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev, 164 166 dst_output); 165 167 }
+3 -3
net/netfilter/Kconfig
··· 126 126 tristate '"CONNMARK" target support' 127 127 depends on NETFILTER_XTABLES 128 128 depends on IP_NF_MANGLE || IP6_NF_MANGLE 129 - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4) 129 + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK) 130 130 help 131 131 This option adds a `CONNMARK' target, which allows one to manipulate 132 132 the connection mark value. Similar to the MARK target, but ··· 187 187 config NETFILTER_XT_MATCH_CONNBYTES 188 188 tristate '"connbytes" per-connection counter match support' 189 189 depends on NETFILTER_XTABLES 190 - depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || NF_CT_ACCT 190 + depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK) 191 191 help 192 192 This option adds a `connbytes' match, which allows you to match the 193 193 number of bytes and/or packets for each direction within a connection. ··· 198 198 config NETFILTER_XT_MATCH_CONNMARK 199 199 tristate '"connmark" connection mark match support' 200 200 depends on NETFILTER_XTABLES 201 - depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || NF_CONNTRACK_MARK 201 + depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK) 202 202 help 203 203 This option adds a `connmark' match, which allows you to match the 204 204 connection mark value previously set for the session by `CONNMARK'.
+5
net/netfilter/nf_conntrack_core.c
··· 1556 1556 { 1557 1557 int i; 1558 1558 1559 + ip_ct_attach = NULL; 1560 + 1559 1561 /* This makes sure all current packets have passed through 1560 1562 netfilter framework. Roll on, two-stage module 1561 1563 delete... */ ··· 1716 1714 for (i = 0; i < PF_MAX; i++) 1717 1715 nf_ct_l3protos[i] = &nf_conntrack_generic_l3proto; 1718 1716 write_unlock_bh(&nf_conntrack_lock); 1717 + 1718 + /* For use by REJECT target */ 1719 + ip_ct_attach = __nf_conntrack_attach; 1719 1720 1720 1721 /* Set up fake conntrack: 1721 1722 - to never be deleted, not in any hashes */
+3 -1
net/netfilter/nf_conntrack_proto_tcp.c
··· 864 864 { 865 865 return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, 866 866 skb->len - dataoff, IPPROTO_TCP, 867 - skb->ip_summed == CHECKSUM_HW ? skb->csum 867 + skb->ip_summed == CHECKSUM_HW 868 + ? csum_sub(skb->csum, 869 + skb_checksum(skb, 0, dataoff, 0)) 868 870 : skb_checksum(skb, dataoff, skb->len - dataoff, 869 871 0)); 870 872 }
+3 -1
net/netfilter/nf_conntrack_proto_udp.c
··· 161 161 { 162 162 return csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr, 163 163 skb->len - dataoff, IPPROTO_UDP, 164 - skb->ip_summed == CHECKSUM_HW ? skb->csum 164 + skb->ip_summed == CHECKSUM_HW 165 + ? csum_sub(skb->csum, 166 + skb_checksum(skb, 0, dataoff, 0)) 165 167 : skb_checksum(skb, dataoff, skb->len - dataoff, 166 168 0)); 167 169 }