11/*
22 * This is NetFlow exporting module (NETFLOW target) for linux
3- * (c) 2008-2013 <abc@telekom.ru>
3+ * (c) 2008-2014 <abc@telekom.ru>
44 *
55 *
66 * This program is free software: you can redistribute it and/or modify
111111#define ipt_target xt_target
112112#endif
113113
114- #define IPT_NETFLOW_VERSION "2.0" /* Note that if you are using git, you
114+ #define IPT_NETFLOW_VERSION "2.0.1" /* Note that if you are using git, you
115115 will see version in other format. */
116116#include "version.h"
117117#ifdef GITVERSION
@@ -383,6 +383,9 @@ static int nf_seq_show(struct seq_file *seq, void *v)
383383#ifdef ENABLE_DEBUGFS
384384 " debugfs"
385385#endif
386+ #ifdef ENABLE_DIRECTION
387+ " dir"
388+ #endif
386389#ifdef HAVE_LLIST
387390 " llist"
388391#endif
@@ -1917,8 +1920,6 @@ static u_int8_t tpl_element_sizes[] = {
19171920 [dot1qCustomerVlanId ] = 2 ,
19181921 [dot1qCustomerPriority ] = 1 ,
19191922 [ethernetType ] = 2 ,
1920- [postNATSourceIPv6Address ] = 16 ,
1921- [postNATDestinationIPv6Address ] = 16 ,
19221923 [IPSecSPI ] = 4 ,
19231924 [observationTimeMilliseconds ] = 8 ,
19241925 [observationTimeMicroseconds ] = 8 ,
@@ -2077,9 +2078,11 @@ static struct base_template template_nat4 = {
20772078 0
20782079 }
20792080};
2081+ #ifdef CONFIG_NF_CONNTRACK_MARK
20802082static struct base_template template_mark = {
20812083 .types = { commonPropertiesId , 0 }
20822084};
2085+ #endif
20832086
20842087struct data_template {
20852088 struct hlist_node hlist ;
@@ -2159,8 +2162,10 @@ static struct data_template *get_template(const int tmask)
21592162 tlist [tnum ++ ] = & template_igmp ;
21602163 if (tmask & BTPL_IPSEC )
21612164 tlist [tnum ++ ] = & template_ipsec ;
2165+ #ifdef CONFIG_NF_CONNTRACK_MARK
21622166 if (tmask & BTPL_MARK )
21632167 tlist [tnum ++ ] = & template_mark ;
2168+ #endif
21642169#ifdef ENABLE_MAC
21652170 if (tmask & BTPL_MAC )
21662171 tlist [tnum ++ ] = & template_mac_ipfix ;
@@ -2340,7 +2345,7 @@ static inline void add_tpl_field(__u8 *ptr, const int type, const struct ipt_net
23402345 case IPV6_DST_ADDR : * (in6_t * )ptr = nf -> tuple .dst .in6 ; break ;
23412346 case IPV6_NEXT_HOP : * (in6_t * )ptr = nf -> nh .in6 ; break ;
23422347 case IPV6_FLOW_LABEL : * ptr ++ = nf -> flow_label >> 16 ;
2343- * (__be16 * )ptr = nf -> flow_label ;
2348+ * (__be16 * )ptr = htons (( __u16 ) nf -> flow_label ) ;
23442349 break ;
23452350 case tcpOptions : * (__be32 * )ptr = htonl (nf -> tcpoptions ); break ;
23462351 case ipv4Options : * (__be32 * )ptr = htonl (nf -> options ); break ;
@@ -2360,7 +2365,7 @@ static inline void add_tpl_field(__u8 *ptr, const int type, const struct ipt_net
23602365 case postNAPTDestinationTransportPort : * (__be16 * )ptr = nf -> nat -> post .d_port ; break ;
23612366 case natEvent : * ptr = nf -> nat -> nat_event ; break ;
23622367#endif
2363- case IPSecSPI : * (__u32 * )ptr = (nf -> tuple .s_port << 16 ) | nf -> tuple .d_port ; break ;
2368+ case IPSecSPI : * (__be32 * )ptr = (nf -> tuple .s_port << 16 ) | nf -> tuple .d_port ; break ;
23642369 case observationTimeMilliseconds :
23652370 * (__be64 * )ptr = cpu_to_be64 (ktime_to_ms (nf -> ts_obs )); break ;
23662371 case observationTimeMicroseconds :
@@ -2432,6 +2437,9 @@ static void netflow_export_flow_tpl(struct ipt_netflow *nf)
24322437 tpl_mask |= BTPL_ICMP ;
24332438 else if (nf -> tuple .protocol == IPPROTO_IGMP )
24342439 tpl_mask |= BTPL_IGMP ;
2440+ else if (nf -> tuple .protocol == IPPROTO_AH ||
2441+ nf -> tuple .protocol == IPPROTO_ESP )
2442+ tpl_mask |= BTPL_IPSEC ;
24352443#ifdef CONFIG_NF_CONNTRACK_MARK
24362444 if (nf -> mark )
24372445 tpl_mask |= BTPL_MARK ;
@@ -3165,6 +3173,15 @@ static unsigned int netflow_target(
31653173 return IPT_CONTINUE ;
31663174 }
31673175
3176+ #ifdef ENABLE_DEBUGFS
3177+ if (atomic_read (& freeze )) {
3178+ NETFLOW_STAT_INC (freeze_err );
3179+ NETFLOW_STAT_INC (pkt_drop );
3180+ NETFLOW_STAT_ADD (traf_drop , pkt_len );
3181+ return IPT_CONTINUE ;
3182+ }
3183+ #endif
3184+
31683185 tuple .l3proto = family ;
31693186 tuple .s_port = 0 ;
31703187 tuple .d_port = 0 ;
@@ -3258,15 +3275,19 @@ static unsigned int netflow_target(
32583275 break ;
32593276 }
32603277 case IPPROTO_AH : {
3261- struct ip_auth_hdr _hdr , * hp ;
3278+ struct ip_auth_hdr _ahdr , * ap ;
32623279
3263- if (likely (hp = skb_header_pointer (skb , ptr , 8 , & _hdr ))) {
3264- tuple .s_port = hp -> spi >> 16 ;
3265- tuple .d_port = hp -> spi ;
3280+ if (likely (ap = skb_header_pointer (skb , ptr , 8 , & _ahdr ))) {
3281+ tuple .s_port = ap -> spi >> 16 ;
3282+ tuple .d_port = ap -> spi ;
32663283 }
3267- hdrlen = (hp -> hdrlen + 2 ) << 2 ;
3284+ hdrlen = (ap -> hdrlen + 2 ) << 2 ;
32683285 break ;
32693286 }
3287+ case IPPROTO_ESP :
3288+ /* After this header everything is encrypted. */
3289+ tuple .protocol = currenthdr ;
3290+ goto do_protocols ;
32703291 default :
32713292 hdrlen = ipv6_optlen (hp );
32723293 }
@@ -3277,15 +3298,6 @@ static unsigned int netflow_target(
32773298 options |= observed_hdrs (currenthdr );
32783299 }
32793300
3280- #ifdef ENABLE_DEBUGFS
3281- if (atomic_read (& freeze )) {
3282- NETFLOW_STAT_INC (freeze_err );
3283- NETFLOW_STAT_INC (pkt_drop );
3284- NETFLOW_STAT_ADD (traf_drop , pkt_len );
3285- return IPT_CONTINUE ;
3286- }
3287- #endif
3288-
32893301do_protocols :
32903302 if (fragment ) {
32913303 /* if conntrack is enabled it should defrag on pre-routing and local-out */
@@ -3325,24 +3337,25 @@ static unsigned int netflow_target(
33253337 break ;
33263338 }
33273339 case IPPROTO_ICMPV6 : {
3328- struct icmp6hdr _icmp6h , * ic ;
3340+ struct icmp6hdr _icmp6h , * ic ;
33293341
3330- if (likely (family == AF_INET6 &&
3331- (ic = skb_header_pointer (skb , ptr , 2 , & _icmp6h ))))
3332- tuple .d_port = htons ((ic -> icmp6_type << 8 ) | ic -> icmp6_code );
3333- break ;
3342+ if (likely (family == AF_INET6 &&
3343+ (ic = skb_header_pointer (skb , ptr , 2 , & _icmp6h ))))
3344+ tuple .d_port = htons ((ic -> icmp6_type << 8 ) | ic -> icmp6_code );
3345+ break ;
33343346 }
33353347 case IPPROTO_IGMP : {
33363348 struct igmphdr _hdr , * hp ;
33373349
3338- if (likely (hp = skb_header_pointer (skb , ptr , 1 , & _hdr )))
3339- tuple .d_port = hp -> type ;
3340- }
3350+ if (likely (hp = skb_header_pointer (skb , ptr , 1 , & _hdr )))
3351+ tuple .d_port = hp -> type ;
33413352 break ;
3353+ }
33423354 case IPPROTO_AH : { /* IPSEC */
33433355 struct ip_auth_hdr _hdr , * hp ;
33443356
3345- if (likely (family == AF_INET && /* For IPv6 it's parsed above. */
3357+ /* This is for IPv4 only. IPv6 it's parsed above. */
3358+ if (likely (family == AF_INET &&
33463359 (hp = skb_header_pointer (skb , ptr , 8 , & _hdr )))) {
33473360 tuple .s_port = hp -> spi >> 16 ;
33483361 tuple .d_port = hp -> spi ;
@@ -3352,12 +3365,14 @@ static unsigned int netflow_target(
33523365 case IPPROTO_ESP : {
33533366 struct ip_esp_hdr _hdr , * hp ;
33543367
3355- if (likely (hp = skb_header_pointer (skb , ptr , 4 , & _hdr )))
3368+ /* This is for both IPv4 and IPv6. */
3369+ if (likely (hp = skb_header_pointer (skb , ptr , 4 , & _hdr ))) {
33563370 tuple .s_port = hp -> spi >> 16 ;
33573371 tuple .d_port = hp -> spi ;
33583372 }
33593373 break ;
3360- }
3374+ }
3375+ }
33613376 } /* not fragmented */
33623377
33633378#ifndef DISABLE_AGGR
0 commit comments