diff options
author | David S. Miller <davem@davemloft.net> | 2010-10-21 11:21:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-21 11:21:34 -0400 |
commit | 9941fb62762253774cc6177d0b9172ece5133fe1 (patch) | |
tree | 641fc2b376e2f84c7023aa0cd8b9d76f954cc3a1 /include/net | |
parent | a5190b4eea1f1c53ee26b3d1176441cafa8e7f79 (diff) | |
parent | 3b1a1ce6f418cb7ab35eb55c8a6575987a524e30 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/inet_hashtables.h | 2 | ||||
-rw-r--r-- | include/net/ip_vs.h | 180 | ||||
-rw-r--r-- | include/net/netfilter/ipv6/nf_defrag_ipv6.h | 6 | ||||
-rw-r--r-- | include/net/netfilter/nf_conntrack_expect.h | 12 | ||||
-rw-r--r-- | include/net/netfilter/nf_nat_protocol.h | 3 | ||||
-rw-r--r-- | include/net/netfilter/nf_tproxy_core.h | 192 | ||||
-rw-r--r-- | include/net/netfilter/xt_log.h | 54 | ||||
-rw-r--r-- | include/net/udp.h | 3 |
8 files changed, 414 insertions, 38 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 74358d1b3f4..e9c2ed8af86 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
@@ -245,7 +245,7 @@ static inline int inet_sk_listen_hashfn(const struct sock *sk) | |||
245 | } | 245 | } |
246 | 246 | ||
247 | /* Caller must disable local BH processing. */ | 247 | /* Caller must disable local BH processing. */ |
248 | extern void __inet_inherit_port(struct sock *sk, struct sock *child); | 248 | extern int __inet_inherit_port(struct sock *sk, struct sock *child); |
249 | 249 | ||
250 | extern void inet_put_port(struct sock *sk); | 250 | extern void inet_put_port(struct sock *sk); |
251 | 251 | ||
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index f976885f686..b7bbd6c28cf 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -25,7 +25,9 @@ | |||
25 | #include <linux/ip.h> | 25 | #include <linux/ip.h> |
26 | #include <linux/ipv6.h> /* for struct ipv6hdr */ | 26 | #include <linux/ipv6.h> /* for struct ipv6hdr */ |
27 | #include <net/ipv6.h> /* for ipv6_addr_copy */ | 27 | #include <net/ipv6.h> /* for ipv6_addr_copy */ |
28 | 28 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | |
29 | #include <net/netfilter/nf_conntrack.h> | ||
30 | #endif | ||
29 | 31 | ||
30 | /* Connections' size value needed by ip_vs_ctl.c */ | 32 | /* Connections' size value needed by ip_vs_ctl.c */ |
31 | extern int ip_vs_conn_tab_size; | 33 | extern int ip_vs_conn_tab_size; |
@@ -134,24 +136,24 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len, | |||
134 | if (net_ratelimit()) \ | 136 | if (net_ratelimit()) \ |
135 | printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \ | 137 | printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \ |
136 | } while (0) | 138 | } while (0) |
137 | #define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) \ | 139 | #define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) \ |
138 | do { \ | 140 | do { \ |
139 | if (level <= ip_vs_get_debug_level()) \ | 141 | if (level <= ip_vs_get_debug_level()) \ |
140 | pp->debug_packet(pp, skb, ofs, msg); \ | 142 | pp->debug_packet(af, pp, skb, ofs, msg); \ |
141 | } while (0) | 143 | } while (0) |
142 | #define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) \ | 144 | #define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) \ |
143 | do { \ | 145 | do { \ |
144 | if (level <= ip_vs_get_debug_level() && \ | 146 | if (level <= ip_vs_get_debug_level() && \ |
145 | net_ratelimit()) \ | 147 | net_ratelimit()) \ |
146 | pp->debug_packet(pp, skb, ofs, msg); \ | 148 | pp->debug_packet(af, pp, skb, ofs, msg); \ |
147 | } while (0) | 149 | } while (0) |
148 | #else /* NO DEBUGGING at ALL */ | 150 | #else /* NO DEBUGGING at ALL */ |
149 | #define IP_VS_DBG_BUF(level, msg...) do {} while (0) | 151 | #define IP_VS_DBG_BUF(level, msg...) do {} while (0) |
150 | #define IP_VS_ERR_BUF(msg...) do {} while (0) | 152 | #define IP_VS_ERR_BUF(msg...) do {} while (0) |
151 | #define IP_VS_DBG(level, msg...) do {} while (0) | 153 | #define IP_VS_DBG(level, msg...) do {} while (0) |
152 | #define IP_VS_DBG_RL(msg...) do {} while (0) | 154 | #define IP_VS_DBG_RL(msg...) do {} while (0) |
153 | #define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) do {} while (0) | 155 | #define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) do {} while (0) |
154 | #define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) do {} while (0) | 156 | #define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) do {} while (0) |
155 | #endif | 157 | #endif |
156 | 158 | ||
157 | #define IP_VS_BUG() BUG() | 159 | #define IP_VS_BUG() BUG() |
@@ -343,7 +345,7 @@ struct ip_vs_protocol { | |||
343 | 345 | ||
344 | int (*app_conn_bind)(struct ip_vs_conn *cp); | 346 | int (*app_conn_bind)(struct ip_vs_conn *cp); |
345 | 347 | ||
346 | void (*debug_packet)(struct ip_vs_protocol *pp, | 348 | void (*debug_packet)(int af, struct ip_vs_protocol *pp, |
347 | const struct sk_buff *skb, | 349 | const struct sk_buff *skb, |
348 | int offset, | 350 | int offset, |
349 | const char *msg); | 351 | const char *msg); |
@@ -355,6 +357,19 @@ struct ip_vs_protocol { | |||
355 | 357 | ||
356 | extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto); | 358 | extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto); |
357 | 359 | ||
360 | struct ip_vs_conn_param { | ||
361 | const union nf_inet_addr *caddr; | ||
362 | const union nf_inet_addr *vaddr; | ||
363 | __be16 cport; | ||
364 | __be16 vport; | ||
365 | __u16 protocol; | ||
366 | u16 af; | ||
367 | |||
368 | const struct ip_vs_pe *pe; | ||
369 | char *pe_data; | ||
370 | __u8 pe_data_len; | ||
371 | }; | ||
372 | |||
358 | /* | 373 | /* |
359 | * IP_VS structure allocated for each dynamically scheduled connection | 374 | * IP_VS structure allocated for each dynamically scheduled connection |
360 | */ | 375 | */ |
@@ -366,6 +381,7 @@ struct ip_vs_conn { | |||
366 | union nf_inet_addr caddr; /* client address */ | 381 | union nf_inet_addr caddr; /* client address */ |
367 | union nf_inet_addr vaddr; /* virtual address */ | 382 | union nf_inet_addr vaddr; /* virtual address */ |
368 | union nf_inet_addr daddr; /* destination address */ | 383 | union nf_inet_addr daddr; /* destination address */ |
384 | volatile __u32 flags; /* status flags */ | ||
369 | __be16 cport; | 385 | __be16 cport; |
370 | __be16 vport; | 386 | __be16 vport; |
371 | __be16 dport; | 387 | __be16 dport; |
@@ -378,7 +394,6 @@ struct ip_vs_conn { | |||
378 | 394 | ||
379 | /* Flags and state transition */ | 395 | /* Flags and state transition */ |
380 | spinlock_t lock; /* lock for state transition */ | 396 | spinlock_t lock; /* lock for state transition */ |
381 | volatile __u16 flags; /* status flags */ | ||
382 | volatile __u16 state; /* state info */ | 397 | volatile __u16 state; /* state info */ |
383 | volatile __u16 old_state; /* old state, to be used for | 398 | volatile __u16 old_state; /* old state, to be used for |
384 | * state transition triggerd | 399 | * state transition triggerd |
@@ -394,6 +409,7 @@ struct ip_vs_conn { | |||
394 | /* packet transmitter for different forwarding methods. If it | 409 | /* packet transmitter for different forwarding methods. If it |
395 | mangles the packet, it must return NF_DROP or better NF_STOLEN, | 410 | mangles the packet, it must return NF_DROP or better NF_STOLEN, |
396 | otherwise this must be changed to a sk_buff **. | 411 | otherwise this must be changed to a sk_buff **. |
412 | NF_ACCEPT can be returned when destination is local. | ||
397 | */ | 413 | */ |
398 | int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, | 414 | int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, |
399 | struct ip_vs_protocol *pp); | 415 | struct ip_vs_protocol *pp); |
@@ -405,6 +421,9 @@ struct ip_vs_conn { | |||
405 | void *app_data; /* Application private data */ | 421 | void *app_data; /* Application private data */ |
406 | struct ip_vs_seq in_seq; /* incoming seq. struct */ | 422 | struct ip_vs_seq in_seq; /* incoming seq. struct */ |
407 | struct ip_vs_seq out_seq; /* outgoing seq. struct */ | 423 | struct ip_vs_seq out_seq; /* outgoing seq. struct */ |
424 | |||
425 | char *pe_data; | ||
426 | __u8 pe_data_len; | ||
408 | }; | 427 | }; |
409 | 428 | ||
410 | 429 | ||
@@ -426,6 +445,7 @@ struct ip_vs_service_user_kern { | |||
426 | 445 | ||
427 | /* virtual service options */ | 446 | /* virtual service options */ |
428 | char *sched_name; | 447 | char *sched_name; |
448 | char *pe_name; | ||
429 | unsigned flags; /* virtual service flags */ | 449 | unsigned flags; /* virtual service flags */ |
430 | unsigned timeout; /* persistent timeout in sec */ | 450 | unsigned timeout; /* persistent timeout in sec */ |
431 | u32 netmask; /* persistent netmask */ | 451 | u32 netmask; /* persistent netmask */ |
@@ -475,6 +495,9 @@ struct ip_vs_service { | |||
475 | struct ip_vs_scheduler *scheduler; /* bound scheduler object */ | 495 | struct ip_vs_scheduler *scheduler; /* bound scheduler object */ |
476 | rwlock_t sched_lock; /* lock sched_data */ | 496 | rwlock_t sched_lock; /* lock sched_data */ |
477 | void *sched_data; /* scheduler application data */ | 497 | void *sched_data; /* scheduler application data */ |
498 | |||
499 | /* alternate persistence engine */ | ||
500 | struct ip_vs_pe *pe; | ||
478 | }; | 501 | }; |
479 | 502 | ||
480 | 503 | ||
@@ -507,6 +530,10 @@ struct ip_vs_dest { | |||
507 | spinlock_t dst_lock; /* lock of dst_cache */ | 530 | spinlock_t dst_lock; /* lock of dst_cache */ |
508 | struct dst_entry *dst_cache; /* destination cache entry */ | 531 | struct dst_entry *dst_cache; /* destination cache entry */ |
509 | u32 dst_rtos; /* RT_TOS(tos) for dst */ | 532 | u32 dst_rtos; /* RT_TOS(tos) for dst */ |
533 | u32 dst_cookie; | ||
534 | #ifdef CONFIG_IP_VS_IPV6 | ||
535 | struct in6_addr dst_saddr; | ||
536 | #endif | ||
510 | 537 | ||
511 | /* for virtual service */ | 538 | /* for virtual service */ |
512 | struct ip_vs_service *svc; /* service it belongs to */ | 539 | struct ip_vs_service *svc; /* service it belongs to */ |
@@ -538,6 +565,21 @@ struct ip_vs_scheduler { | |||
538 | const struct sk_buff *skb); | 565 | const struct sk_buff *skb); |
539 | }; | 566 | }; |
540 | 567 | ||
568 | /* The persistence engine object */ | ||
569 | struct ip_vs_pe { | ||
570 | struct list_head n_list; /* d-linked list head */ | ||
571 | char *name; /* scheduler name */ | ||
572 | atomic_t refcnt; /* reference counter */ | ||
573 | struct module *module; /* THIS_MODULE/NULL */ | ||
574 | |||
575 | /* get the connection template, if any */ | ||
576 | int (*fill_param)(struct ip_vs_conn_param *p, struct sk_buff *skb); | ||
577 | bool (*ct_match)(const struct ip_vs_conn_param *p, | ||
578 | struct ip_vs_conn *ct); | ||
579 | u32 (*hashkey_raw)(const struct ip_vs_conn_param *p, u32 initval, | ||
580 | bool inverse); | ||
581 | int (*show_pe_data)(const struct ip_vs_conn *cp, char *buf); | ||
582 | }; | ||
541 | 583 | ||
542 | /* | 584 | /* |
543 | * The application module object (a.k.a. app incarnation) | 585 | * The application module object (a.k.a. app incarnation) |
@@ -556,11 +598,19 @@ struct ip_vs_app { | |||
556 | __be16 port; /* port number in net order */ | 598 | __be16 port; /* port number in net order */ |
557 | atomic_t usecnt; /* usage counter */ | 599 | atomic_t usecnt; /* usage counter */ |
558 | 600 | ||
559 | /* output hook: return false if can't linearize. diff set for TCP. */ | 601 | /* |
602 | * output hook: Process packet in inout direction, diff set for TCP. | ||
603 | * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, | ||
604 | * 2=Mangled but checksum was not updated | ||
605 | */ | ||
560 | int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *, | 606 | int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *, |
561 | struct sk_buff *, int *diff); | 607 | struct sk_buff *, int *diff); |
562 | 608 | ||
563 | /* input hook: return false if can't linearize. diff set for TCP. */ | 609 | /* |
610 | * input hook: Process packet in outin direction, diff set for TCP. | ||
611 | * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, | ||
612 | * 2=Mangled but checksum was not updated | ||
613 | */ | ||
564 | int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *, | 614 | int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *, |
565 | struct sk_buff *, int *diff); | 615 | struct sk_buff *, int *diff); |
566 | 616 | ||
@@ -624,13 +674,25 @@ enum { | |||
624 | IP_VS_DIR_LAST, | 674 | IP_VS_DIR_LAST, |
625 | }; | 675 | }; |
626 | 676 | ||
627 | extern struct ip_vs_conn *ip_vs_conn_in_get | 677 | static inline void ip_vs_conn_fill_param(int af, int protocol, |
628 | (int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, | 678 | const union nf_inet_addr *caddr, |
629 | const union nf_inet_addr *d_addr, __be16 d_port); | 679 | __be16 cport, |
680 | const union nf_inet_addr *vaddr, | ||
681 | __be16 vport, | ||
682 | struct ip_vs_conn_param *p) | ||
683 | { | ||
684 | p->af = af; | ||
685 | p->protocol = protocol; | ||
686 | p->caddr = caddr; | ||
687 | p->cport = cport; | ||
688 | p->vaddr = vaddr; | ||
689 | p->vport = vport; | ||
690 | p->pe = NULL; | ||
691 | p->pe_data = NULL; | ||
692 | } | ||
630 | 693 | ||
631 | extern struct ip_vs_conn *ip_vs_ct_in_get | 694 | struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p); |
632 | (int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, | 695 | struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p); |
633 | const union nf_inet_addr *d_addr, __be16 d_port); | ||
634 | 696 | ||
635 | struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, | 697 | struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, |
636 | struct ip_vs_protocol *pp, | 698 | struct ip_vs_protocol *pp, |
@@ -638,9 +700,7 @@ struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, | |||
638 | unsigned int proto_off, | 700 | unsigned int proto_off, |
639 | int inverse); | 701 | int inverse); |
640 | 702 | ||
641 | extern struct ip_vs_conn *ip_vs_conn_out_get | 703 | struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p); |
642 | (int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, | ||
643 | const union nf_inet_addr *d_addr, __be16 d_port); | ||
644 | 704 | ||
645 | struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, | 705 | struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, |
646 | struct ip_vs_protocol *pp, | 706 | struct ip_vs_protocol *pp, |
@@ -656,11 +716,10 @@ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp) | |||
656 | extern void ip_vs_conn_put(struct ip_vs_conn *cp); | 716 | extern void ip_vs_conn_put(struct ip_vs_conn *cp); |
657 | extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport); | 717 | extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport); |
658 | 718 | ||
659 | extern struct ip_vs_conn * | 719 | struct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p, |
660 | ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, | 720 | const union nf_inet_addr *daddr, |
661 | const union nf_inet_addr *vaddr, __be16 vport, | 721 | __be16 dport, unsigned flags, |
662 | const union nf_inet_addr *daddr, __be16 dport, unsigned flags, | 722 | struct ip_vs_dest *dest); |
663 | struct ip_vs_dest *dest); | ||
664 | extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp); | 723 | extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp); |
665 | 724 | ||
666 | extern const char * ip_vs_state_name(__u16 proto, int state); | 725 | extern const char * ip_vs_state_name(__u16 proto, int state); |
@@ -751,6 +810,12 @@ extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb); | |||
751 | extern int ip_vs_app_init(void); | 810 | extern int ip_vs_app_init(void); |
752 | extern void ip_vs_app_cleanup(void); | 811 | extern void ip_vs_app_cleanup(void); |
753 | 812 | ||
813 | void ip_vs_bind_pe(struct ip_vs_service *svc, struct ip_vs_pe *pe); | ||
814 | void ip_vs_unbind_pe(struct ip_vs_service *svc); | ||
815 | int register_ip_vs_pe(struct ip_vs_pe *pe); | ||
816 | int unregister_ip_vs_pe(struct ip_vs_pe *pe); | ||
817 | extern struct ip_vs_pe *ip_vs_pe_get(const char *name); | ||
818 | extern void ip_vs_pe_put(struct ip_vs_pe *pe); | ||
754 | 819 | ||
755 | /* | 820 | /* |
756 | * IPVS protocol functions (from ip_vs_proto.c) | 821 | * IPVS protocol functions (from ip_vs_proto.c) |
@@ -763,7 +828,8 @@ extern int | |||
763 | ip_vs_set_state_timeout(int *table, int num, const char *const *names, | 828 | ip_vs_set_state_timeout(int *table, int num, const char *const *names, |
764 | const char *name, int to); | 829 | const char *name, int to); |
765 | extern void | 830 | extern void |
766 | ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb, | 831 | ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, |
832 | const struct sk_buff *skb, | ||
767 | int offset, const char *msg); | 833 | int offset, const char *msg); |
768 | 834 | ||
769 | extern struct ip_vs_protocol ip_vs_protocol_tcp; | 835 | extern struct ip_vs_protocol ip_vs_protocol_tcp; |
@@ -785,7 +851,8 @@ extern int ip_vs_unbind_scheduler(struct ip_vs_service *svc); | |||
785 | extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name); | 851 | extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name); |
786 | extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); | 852 | extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); |
787 | extern struct ip_vs_conn * | 853 | extern struct ip_vs_conn * |
788 | ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb); | 854 | ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, |
855 | struct ip_vs_protocol *pp, int *ignored); | ||
789 | extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | 856 | extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, |
790 | struct ip_vs_protocol *pp); | 857 | struct ip_vs_protocol *pp); |
791 | 858 | ||
@@ -798,6 +865,8 @@ extern int sysctl_ip_vs_expire_nodest_conn; | |||
798 | extern int sysctl_ip_vs_expire_quiescent_template; | 865 | extern int sysctl_ip_vs_expire_quiescent_template; |
799 | extern int sysctl_ip_vs_sync_threshold[2]; | 866 | extern int sysctl_ip_vs_sync_threshold[2]; |
800 | extern int sysctl_ip_vs_nat_icmp_send; | 867 | extern int sysctl_ip_vs_nat_icmp_send; |
868 | extern int sysctl_ip_vs_conntrack; | ||
869 | extern int sysctl_ip_vs_snat_reroute; | ||
801 | extern struct ip_vs_stats ip_vs_stats; | 870 | extern struct ip_vs_stats ip_vs_stats; |
802 | extern const struct ctl_path net_vs_ctl_path[]; | 871 | extern const struct ctl_path net_vs_ctl_path[]; |
803 | 872 | ||
@@ -955,8 +1024,65 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) | |||
955 | return csum_partial(diff, sizeof(diff), oldsum); | 1024 | return csum_partial(diff, sizeof(diff), oldsum); |
956 | } | 1025 | } |
957 | 1026 | ||
1027 | /* | ||
1028 | * Forget current conntrack (unconfirmed) and attach notrack entry | ||
1029 | */ | ||
1030 | static inline void ip_vs_notrack(struct sk_buff *skb) | ||
1031 | { | ||
1032 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
1033 | enum ip_conntrack_info ctinfo; | ||
1034 | struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); | ||
1035 | |||
1036 | if (!ct || !nf_ct_is_untracked(ct)) { | ||
1037 | nf_reset(skb); | ||
1038 | skb->nfct = &nf_ct_untracked_get()->ct_general; | ||
1039 | skb->nfctinfo = IP_CT_NEW; | ||
1040 | nf_conntrack_get(skb->nfct); | ||
1041 | } | ||
1042 | #endif | ||
1043 | } | ||
1044 | |||
1045 | #ifdef CONFIG_IP_VS_NFCT | ||
1046 | /* | ||
1047 | * Netfilter connection tracking | ||
1048 | * (from ip_vs_nfct.c) | ||
1049 | */ | ||
1050 | static inline int ip_vs_conntrack_enabled(void) | ||
1051 | { | ||
1052 | return sysctl_ip_vs_conntrack; | ||
1053 | } | ||
1054 | |||
958 | extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, | 1055 | extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, |
959 | int outin); | 1056 | int outin); |
1057 | extern int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp); | ||
1058 | extern void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct, | ||
1059 | struct ip_vs_conn *cp, u_int8_t proto, | ||
1060 | const __be16 port, int from_rs); | ||
1061 | extern void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp); | ||
1062 | |||
1063 | #else | ||
1064 | |||
1065 | static inline int ip_vs_conntrack_enabled(void) | ||
1066 | { | ||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1070 | static inline void ip_vs_update_conntrack(struct sk_buff *skb, | ||
1071 | struct ip_vs_conn *cp, int outin) | ||
1072 | { | ||
1073 | } | ||
1074 | |||
1075 | static inline int ip_vs_confirm_conntrack(struct sk_buff *skb, | ||
1076 | struct ip_vs_conn *cp) | ||
1077 | { | ||
1078 | return NF_ACCEPT; | ||
1079 | } | ||
1080 | |||
1081 | static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp) | ||
1082 | { | ||
1083 | } | ||
1084 | /* CONFIG_IP_VS_NFCT */ | ||
1085 | #endif | ||
960 | 1086 | ||
961 | #endif /* __KERNEL__ */ | 1087 | #endif /* __KERNEL__ */ |
962 | 1088 | ||
diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h new file mode 100644 index 00000000000..94dd54d76b4 --- /dev/null +++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _NF_DEFRAG_IPV6_H | ||
2 | #define _NF_DEFRAG_IPV6_H | ||
3 | |||
4 | extern void nf_defrag_ipv6_enable(void); | ||
5 | |||
6 | #endif /* _NF_DEFRAG_IPV6_H */ | ||
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 11e815084fc..0f8a8c58753 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h | |||
@@ -67,9 +67,6 @@ struct nf_conntrack_expect_policy { | |||
67 | 67 | ||
68 | #define NF_CT_EXPECT_CLASS_DEFAULT 0 | 68 | #define NF_CT_EXPECT_CLASS_DEFAULT 0 |
69 | 69 | ||
70 | #define NF_CT_EXPECT_PERMANENT 0x1 | ||
71 | #define NF_CT_EXPECT_INACTIVE 0x2 | ||
72 | |||
73 | int nf_conntrack_expect_init(struct net *net); | 70 | int nf_conntrack_expect_init(struct net *net); |
74 | void nf_conntrack_expect_fini(struct net *net); | 71 | void nf_conntrack_expect_fini(struct net *net); |
75 | 72 | ||
@@ -85,9 +82,16 @@ struct nf_conntrack_expect * | |||
85 | nf_ct_find_expectation(struct net *net, u16 zone, | 82 | nf_ct_find_expectation(struct net *net, u16 zone, |
86 | const struct nf_conntrack_tuple *tuple); | 83 | const struct nf_conntrack_tuple *tuple); |
87 | 84 | ||
88 | void nf_ct_unlink_expect(struct nf_conntrack_expect *exp); | 85 | void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, |
86 | u32 pid, int report); | ||
87 | static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) | ||
88 | { | ||
89 | nf_ct_unlink_expect_report(exp, 0, 0); | ||
90 | } | ||
91 | |||
89 | void nf_ct_remove_expectations(struct nf_conn *ct); | 92 | void nf_ct_remove_expectations(struct nf_conn *ct); |
90 | void nf_ct_unexpect_related(struct nf_conntrack_expect *exp); | 93 | void nf_ct_unexpect_related(struct nf_conntrack_expect *exp); |
94 | void nf_ct_remove_userspace_expectations(void); | ||
91 | 95 | ||
92 | /* Allocate space for an expectation: this is mandatory before calling | 96 | /* Allocate space for an expectation: this is mandatory before calling |
93 | nf_ct_expect_related. You will have to call put afterwards. */ | 97 | nf_ct_expect_related. You will have to call put afterwards. */ |
diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h index df17bac46bf..93cc90d28e6 100644 --- a/include/net/netfilter/nf_nat_protocol.h +++ b/include/net/netfilter/nf_nat_protocol.h | |||
@@ -45,9 +45,6 @@ struct nf_nat_protocol { | |||
45 | extern int nf_nat_protocol_register(const struct nf_nat_protocol *proto); | 45 | extern int nf_nat_protocol_register(const struct nf_nat_protocol *proto); |
46 | extern void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto); | 46 | extern void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto); |
47 | 47 | ||
48 | extern const struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol); | ||
49 | extern void nf_nat_proto_put(const struct nf_nat_protocol *proto); | ||
50 | |||
51 | /* Built-in protocols. */ | 48 | /* Built-in protocols. */ |
52 | extern const struct nf_nat_protocol nf_nat_protocol_tcp; | 49 | extern const struct nf_nat_protocol nf_nat_protocol_tcp; |
53 | extern const struct nf_nat_protocol nf_nat_protocol_udp; | 50 | extern const struct nf_nat_protocol nf_nat_protocol_udp; |
diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h index 208b46f4d6d..cd85b3bc832 100644 --- a/include/net/netfilter/nf_tproxy_core.h +++ b/include/net/netfilter/nf_tproxy_core.h | |||
@@ -5,15 +5,201 @@ | |||
5 | #include <linux/in.h> | 5 | #include <linux/in.h> |
6 | #include <linux/skbuff.h> | 6 | #include <linux/skbuff.h> |
7 | #include <net/sock.h> | 7 | #include <net/sock.h> |
8 | #include <net/inet_sock.h> | 8 | #include <net/inet_hashtables.h> |
9 | #include <net/inet6_hashtables.h> | ||
9 | #include <net/tcp.h> | 10 | #include <net/tcp.h> |
10 | 11 | ||
12 | #define NFT_LOOKUP_ANY 0 | ||
13 | #define NFT_LOOKUP_LISTENER 1 | ||
14 | #define NFT_LOOKUP_ESTABLISHED 2 | ||
15 | |||
11 | /* look up and get a reference to a matching socket */ | 16 | /* look up and get a reference to a matching socket */ |
12 | extern struct sock * | 17 | |
18 | |||
19 | /* This function is used by the 'TPROXY' target and the 'socket' | ||
20 | * match. The following lookups are supported: | ||
21 | * | ||
22 | * Explicit TProxy target rule | ||
23 | * =========================== | ||
24 | * | ||
25 | * This is used when the user wants to intercept a connection matching | ||
26 | * an explicit iptables rule. In this case the sockets are assumed | ||
27 | * matching in preference order: | ||
28 | * | ||
29 | * - match: if there's a fully established connection matching the | ||
30 | * _packet_ tuple, it is returned, assuming the redirection | ||
31 | * already took place and we process a packet belonging to an | ||
32 | * established connection | ||
33 | * | ||
34 | * - match: if there's a listening socket matching the redirection | ||
35 | * (e.g. on-port & on-ip of the connection), it is returned, | ||
36 | * regardless if it was bound to 0.0.0.0 or an explicit | ||
37 | * address. The reasoning is that if there's an explicit rule, it | ||
38 | * does not really matter if the listener is bound to an interface | ||
39 | * or to 0. The user already stated that he wants redirection | ||
40 | * (since he added the rule). | ||
41 | * | ||
42 | * "socket" match based redirection (no specific rule) | ||
43 | * =================================================== | ||
44 | * | ||
45 | * There are connections with dynamic endpoints (e.g. FTP data | ||
46 | * connection) that the user is unable to add explicit rules | ||
47 | * for. These are taken care of by a generic "socket" rule. It is | ||
48 | * assumed that the proxy application is trusted to open such | ||
49 | * connections without explicit iptables rule (except of course the | ||
50 | * generic 'socket' rule). In this case the following sockets are | ||
51 | * matched in preference order: | ||
52 | * | ||
53 | * - match: if there's a fully established connection matching the | ||
54 | * _packet_ tuple | ||
55 | * | ||
56 | * - match: if there's a non-zero bound listener (possibly with a | ||
57 | * non-local address) We don't accept zero-bound listeners, since | ||
58 | * then local services could intercept traffic going through the | ||
59 | * box. | ||
60 | * | ||
61 | * Please note that there's an overlap between what a TPROXY target | ||
62 | * and a socket match will match. Normally if you have both rules the | ||
63 | * "socket" match will be the first one, effectively all packets | ||
64 | * belonging to established connections going through that one. | ||
65 | */ | ||
66 | static inline struct sock * | ||
13 | nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, | 67 | nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, |
14 | const __be32 saddr, const __be32 daddr, | 68 | const __be32 saddr, const __be32 daddr, |
15 | const __be16 sport, const __be16 dport, | 69 | const __be16 sport, const __be16 dport, |
16 | const struct net_device *in, bool listening); | 70 | const struct net_device *in, int lookup_type) |
71 | { | ||
72 | struct sock *sk; | ||
73 | |||
74 | /* look up socket */ | ||
75 | switch (protocol) { | ||
76 | case IPPROTO_TCP: | ||
77 | switch (lookup_type) { | ||
78 | case NFT_LOOKUP_ANY: | ||
79 | sk = __inet_lookup(net, &tcp_hashinfo, | ||
80 | saddr, sport, daddr, dport, | ||
81 | in->ifindex); | ||
82 | break; | ||
83 | case NFT_LOOKUP_LISTENER: | ||
84 | sk = inet_lookup_listener(net, &tcp_hashinfo, | ||
85 | daddr, dport, | ||
86 | in->ifindex); | ||
87 | |||
88 | /* NOTE: we return listeners even if bound to | ||
89 | * 0.0.0.0, those are filtered out in | ||
90 | * xt_socket, since xt_TPROXY needs 0 bound | ||
91 | * listeners too */ | ||
92 | |||
93 | break; | ||
94 | case NFT_LOOKUP_ESTABLISHED: | ||
95 | sk = inet_lookup_established(net, &tcp_hashinfo, | ||
96 | saddr, sport, daddr, dport, | ||
97 | in->ifindex); | ||
98 | break; | ||
99 | default: | ||
100 | WARN_ON(1); | ||
101 | sk = NULL; | ||
102 | break; | ||
103 | } | ||
104 | break; | ||
105 | case IPPROTO_UDP: | ||
106 | sk = udp4_lib_lookup(net, saddr, sport, daddr, dport, | ||
107 | in->ifindex); | ||
108 | if (sk && lookup_type != NFT_LOOKUP_ANY) { | ||
109 | int connected = (sk->sk_state == TCP_ESTABLISHED); | ||
110 | int wildcard = (inet_sk(sk)->inet_rcv_saddr == 0); | ||
111 | |||
112 | /* NOTE: we return listeners even if bound to | ||
113 | * 0.0.0.0, those are filtered out in | ||
114 | * xt_socket, since xt_TPROXY needs 0 bound | ||
115 | * listeners too */ | ||
116 | if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) || | ||
117 | (lookup_type == NFT_LOOKUP_LISTENER && connected)) { | ||
118 | sock_put(sk); | ||
119 | sk = NULL; | ||
120 | } | ||
121 | } | ||
122 | break; | ||
123 | default: | ||
124 | WARN_ON(1); | ||
125 | sk = NULL; | ||
126 | } | ||
127 | |||
128 | pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n", | ||
129 | protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk); | ||
130 | |||
131 | return sk; | ||
132 | } | ||
133 | |||
134 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
135 | static inline struct sock * | ||
136 | nf_tproxy_get_sock_v6(struct net *net, const u8 protocol, | ||
137 | const struct in6_addr *saddr, const struct in6_addr *daddr, | ||
138 | const __be16 sport, const __be16 dport, | ||
139 | const struct net_device *in, int lookup_type) | ||
140 | { | ||
141 | struct sock *sk; | ||
142 | |||
143 | /* look up socket */ | ||
144 | switch (protocol) { | ||
145 | case IPPROTO_TCP: | ||
146 | switch (lookup_type) { | ||
147 | case NFT_LOOKUP_ANY: | ||
148 | sk = inet6_lookup(net, &tcp_hashinfo, | ||
149 | saddr, sport, daddr, dport, | ||
150 | in->ifindex); | ||
151 | break; | ||
152 | case NFT_LOOKUP_LISTENER: | ||
153 | sk = inet6_lookup_listener(net, &tcp_hashinfo, | ||
154 | daddr, ntohs(dport), | ||
155 | in->ifindex); | ||
156 | |||
157 | /* NOTE: we return listeners even if bound to | ||
158 | * 0.0.0.0, those are filtered out in | ||
159 | * xt_socket, since xt_TPROXY needs 0 bound | ||
160 | * listeners too */ | ||
161 | |||
162 | break; | ||
163 | case NFT_LOOKUP_ESTABLISHED: | ||
164 | sk = __inet6_lookup_established(net, &tcp_hashinfo, | ||
165 | saddr, sport, daddr, ntohs(dport), | ||
166 | in->ifindex); | ||
167 | break; | ||
168 | default: | ||
169 | WARN_ON(1); | ||
170 | sk = NULL; | ||
171 | break; | ||
172 | } | ||
173 | break; | ||
174 | case IPPROTO_UDP: | ||
175 | sk = udp6_lib_lookup(net, saddr, sport, daddr, dport, | ||
176 | in->ifindex); | ||
177 | if (sk && lookup_type != NFT_LOOKUP_ANY) { | ||
178 | int connected = (sk->sk_state == TCP_ESTABLISHED); | ||
179 | int wildcard = ipv6_addr_any(&inet6_sk(sk)->rcv_saddr); | ||
180 | |||
181 | /* NOTE: we return listeners even if bound to | ||
182 | * 0.0.0.0, those are filtered out in | ||
183 | * xt_socket, since xt_TPROXY needs 0 bound | ||
184 | * listeners too */ | ||
185 | if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) || | ||
186 | (lookup_type == NFT_LOOKUP_LISTENER && connected)) { | ||
187 | sock_put(sk); | ||
188 | sk = NULL; | ||
189 | } | ||
190 | } | ||
191 | break; | ||
192 | default: | ||
193 | WARN_ON(1); | ||
194 | sk = NULL; | ||
195 | } | ||
196 | |||
197 | pr_debug("tproxy socket lookup: proto %u %pI6:%u -> %pI6:%u, lookup type: %d, sock %p\n", | ||
198 | protocol, saddr, ntohs(sport), daddr, ntohs(dport), lookup_type, sk); | ||
199 | |||
200 | return sk; | ||
201 | } | ||
202 | #endif | ||
17 | 203 | ||
18 | static inline void | 204 | static inline void |
19 | nf_tproxy_put_sock(struct sock *sk) | 205 | nf_tproxy_put_sock(struct sock *sk) |
diff --git a/include/net/netfilter/xt_log.h b/include/net/netfilter/xt_log.h new file mode 100644 index 00000000000..0dfb34a5b53 --- /dev/null +++ b/include/net/netfilter/xt_log.h | |||
@@ -0,0 +1,54 @@ | |||
1 | #define S_SIZE (1024 - (sizeof(unsigned int) + 1)) | ||
2 | |||
3 | struct sbuff { | ||
4 | unsigned int count; | ||
5 | char buf[S_SIZE + 1]; | ||
6 | }; | ||
7 | static struct sbuff emergency, *emergency_ptr = &emergency; | ||
8 | |||
9 | static int sb_add(struct sbuff *m, const char *f, ...) | ||
10 | { | ||
11 | va_list args; | ||
12 | int len; | ||
13 | |||
14 | if (likely(m->count < S_SIZE)) { | ||
15 | va_start(args, f); | ||
16 | len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args); | ||
17 | va_end(args); | ||
18 | if (likely(m->count + len < S_SIZE)) { | ||
19 | m->count += len; | ||
20 | return 0; | ||
21 | } | ||
22 | } | ||
23 | m->count = S_SIZE; | ||
24 | printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n"); | ||
25 | return -1; | ||
26 | } | ||
27 | |||
28 | static struct sbuff *sb_open(void) | ||
29 | { | ||
30 | struct sbuff *m = kmalloc(sizeof(*m), GFP_ATOMIC); | ||
31 | |||
32 | if (unlikely(!m)) { | ||
33 | local_bh_disable(); | ||
34 | do { | ||
35 | m = xchg(&emergency_ptr, NULL); | ||
36 | } while (!m); | ||
37 | } | ||
38 | m->count = 0; | ||
39 | return m; | ||
40 | } | ||
41 | |||
42 | static void sb_close(struct sbuff *m) | ||
43 | { | ||
44 | m->buf[m->count] = 0; | ||
45 | printk("%s\n", m->buf); | ||
46 | |||
47 | if (likely(m != &emergency)) | ||
48 | kfree(m); | ||
49 | else { | ||
50 | xchg(&emergency_ptr, m); | ||
51 | local_bh_enable(); | ||
52 | } | ||
53 | } | ||
54 | |||
diff --git a/include/net/udp.h b/include/net/udp.h index a184d3496b1..200b82848c9 100644 --- a/include/net/udp.h +++ b/include/net/udp.h | |||
@@ -183,6 +183,9 @@ extern int udp_lib_setsockopt(struct sock *sk, int level, int optname, | |||
183 | extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, | 183 | extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, |
184 | __be32 daddr, __be16 dport, | 184 | __be32 daddr, __be16 dport, |
185 | int dif); | 185 | int dif); |
186 | extern struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport, | ||
187 | const struct in6_addr *daddr, __be16 dport, | ||
188 | int dif); | ||
186 | 189 | ||
187 | /* | 190 | /* |
188 | * SNMP statistics for UDP and UDP-Lite | 191 | * SNMP statistics for UDP and UDP-Lite |