1
1
/*
2
2
* This is NetFlow exporting module (NETFLOW target) for linux
3
- * (c) 2008-2013 <abc@telekom.ru>
3
+ * (c) 2008-2014 <abc@telekom.ru>
4
4
*
5
5
*
6
6
* This program is free software: you can redistribute it and/or modify
111
111
#define ipt_target xt_target
112
112
#endif
113
113
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
115
115
will see version in other format. */
116
116
#include "version.h"
117
117
#ifdef GITVERSION
@@ -383,6 +383,9 @@ static int nf_seq_show(struct seq_file *seq, void *v)
383
383
#ifdef ENABLE_DEBUGFS
384
384
" debugfs"
385
385
#endif
386
+ #ifdef ENABLE_DIRECTION
387
+ " dir"
388
+ #endif
386
389
#ifdef HAVE_LLIST
387
390
" llist"
388
391
#endif
@@ -1917,8 +1920,6 @@ static u_int8_t tpl_element_sizes[] = {
1917
1920
[dot1qCustomerVlanId ] = 2 ,
1918
1921
[dot1qCustomerPriority ] = 1 ,
1919
1922
[ethernetType ] = 2 ,
1920
- [postNATSourceIPv6Address ] = 16 ,
1921
- [postNATDestinationIPv6Address ] = 16 ,
1922
1923
[IPSecSPI ] = 4 ,
1923
1924
[observationTimeMilliseconds ] = 8 ,
1924
1925
[observationTimeMicroseconds ] = 8 ,
@@ -2077,9 +2078,11 @@ static struct base_template template_nat4 = {
2077
2078
0
2078
2079
}
2079
2080
};
2081
+ #ifdef CONFIG_NF_CONNTRACK_MARK
2080
2082
static struct base_template template_mark = {
2081
2083
.types = { commonPropertiesId , 0 }
2082
2084
};
2085
+ #endif
2083
2086
2084
2087
struct data_template {
2085
2088
struct hlist_node hlist ;
@@ -2159,8 +2162,10 @@ static struct data_template *get_template(const int tmask)
2159
2162
tlist [tnum ++ ] = & template_igmp ;
2160
2163
if (tmask & BTPL_IPSEC )
2161
2164
tlist [tnum ++ ] = & template_ipsec ;
2165
+ #ifdef CONFIG_NF_CONNTRACK_MARK
2162
2166
if (tmask & BTPL_MARK )
2163
2167
tlist [tnum ++ ] = & template_mark ;
2168
+ #endif
2164
2169
#ifdef ENABLE_MAC
2165
2170
if (tmask & BTPL_MAC )
2166
2171
tlist [tnum ++ ] = & template_mac_ipfix ;
@@ -2340,7 +2345,7 @@ static inline void add_tpl_field(__u8 *ptr, const int type, const struct ipt_net
2340
2345
case IPV6_DST_ADDR : * (in6_t * )ptr = nf -> tuple .dst .in6 ; break ;
2341
2346
case IPV6_NEXT_HOP : * (in6_t * )ptr = nf -> nh .in6 ; break ;
2342
2347
case IPV6_FLOW_LABEL : * ptr ++ = nf -> flow_label >> 16 ;
2343
- * (__be16 * )ptr = nf -> flow_label ;
2348
+ * (__be16 * )ptr = htons (( __u16 ) nf -> flow_label ) ;
2344
2349
break ;
2345
2350
case tcpOptions : * (__be32 * )ptr = htonl (nf -> tcpoptions ); break ;
2346
2351
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
2360
2365
case postNAPTDestinationTransportPort : * (__be16 * )ptr = nf -> nat -> post .d_port ; break ;
2361
2366
case natEvent : * ptr = nf -> nat -> nat_event ; break ;
2362
2367
#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 ;
2364
2369
case observationTimeMilliseconds :
2365
2370
* (__be64 * )ptr = cpu_to_be64 (ktime_to_ms (nf -> ts_obs )); break ;
2366
2371
case observationTimeMicroseconds :
@@ -2432,6 +2437,9 @@ static void netflow_export_flow_tpl(struct ipt_netflow *nf)
2432
2437
tpl_mask |= BTPL_ICMP ;
2433
2438
else if (nf -> tuple .protocol == IPPROTO_IGMP )
2434
2439
tpl_mask |= BTPL_IGMP ;
2440
+ else if (nf -> tuple .protocol == IPPROTO_AH ||
2441
+ nf -> tuple .protocol == IPPROTO_ESP )
2442
+ tpl_mask |= BTPL_IPSEC ;
2435
2443
#ifdef CONFIG_NF_CONNTRACK_MARK
2436
2444
if (nf -> mark )
2437
2445
tpl_mask |= BTPL_MARK ;
@@ -3165,6 +3173,15 @@ static unsigned int netflow_target(
3165
3173
return IPT_CONTINUE ;
3166
3174
}
3167
3175
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
+
3168
3185
tuple .l3proto = family ;
3169
3186
tuple .s_port = 0 ;
3170
3187
tuple .d_port = 0 ;
@@ -3258,15 +3275,19 @@ static unsigned int netflow_target(
3258
3275
break ;
3259
3276
}
3260
3277
case IPPROTO_AH : {
3261
- struct ip_auth_hdr _hdr , * hp ;
3278
+ struct ip_auth_hdr _ahdr , * ap ;
3262
3279
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 ;
3266
3283
}
3267
- hdrlen = (hp -> hdrlen + 2 ) << 2 ;
3284
+ hdrlen = (ap -> hdrlen + 2 ) << 2 ;
3268
3285
break ;
3269
3286
}
3287
+ case IPPROTO_ESP :
3288
+ /* After this header everything is encrypted. */
3289
+ tuple .protocol = currenthdr ;
3290
+ goto do_protocols ;
3270
3291
default :
3271
3292
hdrlen = ipv6_optlen (hp );
3272
3293
}
@@ -3277,15 +3298,6 @@ static unsigned int netflow_target(
3277
3298
options |= observed_hdrs (currenthdr );
3278
3299
}
3279
3300
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
-
3289
3301
do_protocols :
3290
3302
if (fragment ) {
3291
3303
/* if conntrack is enabled it should defrag on pre-routing and local-out */
@@ -3325,24 +3337,25 @@ static unsigned int netflow_target(
3325
3337
break ;
3326
3338
}
3327
3339
case IPPROTO_ICMPV6 : {
3328
- struct icmp6hdr _icmp6h , * ic ;
3340
+ struct icmp6hdr _icmp6h , * ic ;
3329
3341
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 ;
3334
3346
}
3335
3347
case IPPROTO_IGMP : {
3336
3348
struct igmphdr _hdr , * hp ;
3337
3349
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 ;
3341
3352
break ;
3353
+ }
3342
3354
case IPPROTO_AH : { /* IPSEC */
3343
3355
struct ip_auth_hdr _hdr , * hp ;
3344
3356
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 &&
3346
3359
(hp = skb_header_pointer (skb , ptr , 8 , & _hdr )))) {
3347
3360
tuple .s_port = hp -> spi >> 16 ;
3348
3361
tuple .d_port = hp -> spi ;
@@ -3352,12 +3365,14 @@ static unsigned int netflow_target(
3352
3365
case IPPROTO_ESP : {
3353
3366
struct ip_esp_hdr _hdr , * hp ;
3354
3367
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 ))) {
3356
3370
tuple .s_port = hp -> spi >> 16 ;
3357
3371
tuple .d_port = hp -> spi ;
3358
3372
}
3359
3373
break ;
3360
- }
3374
+ }
3375
+ }
3361
3376
} /* not fragmented */
3362
3377
3363
3378
#ifndef DISABLE_AGGR
0 commit comments