Skip to content

Commit f97e986

Browse files
committed
Implements #36: Decapsulate MPLS in promisc mode.
./configure --promisc-mpls to enable. It's OK to fully decapsualte them there because packets captured in promisc mode (or 'otherhost' packets) are only visible into raw PREROUTING chain and then dropped w/o routing. Thanks to mzi77@github for feature request, discussion and help.
1 parent 57d3cbf commit f97e986

File tree

5 files changed

+61
-9
lines changed

5 files changed

+61
-9
lines changed

Diff for: README

+11-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ ipt_NETFLOW linux 2.6.x-3.x kernel module by <[email protected]> -- 2008-2015.
5252
* SNMP-index translation rules, let convert meaningless and unstable
5353
interface indexes (ifIndex) to more meaningful numbering scheme.
5454

55-
* Easy support for catching mirrored traffic with promisc option.
55+
* Easy support for catching mirrored traffic with promisc option. Which is
56+
also supporting optional MPLS decapsulation.
5657

5758

5859
============================
@@ -228,13 +229,20 @@ ipt_NETFLOW linux 2.6.x-3.x kernel module by <[email protected]> -- 2008-2015.
228229
case you will want to install it manually.
229230

230231
--enable-physdev
231-
232232
Export ingressPhysicalInterface(252) and egressPhysicalInterface(253)
233233
(relevant for bridges) in V9 and IPFIX. If your collector does not
234234
support these Elements but you still need physdevs then use
235235
--enable-physdev-override, in that case physdevs will override normal
236236
interface numbers ingressInterface(10) and egressInterface(14).
237237

238+
--enable-promisc
239+
Enables capturing of promiscuous packets into raw/PREROUTING chain.
240+
See README.promisc Solution 1 for usage details and example.
241+
242+
--promisc-mpls
243+
Enables MPLS label stack decapsulation for promiscuous packets. (For
244+
IPv4 and IPv6 packets only).
245+
238246

239247
===========
240248
= RUNNING =
@@ -538,7 +546,7 @@ ipt_NETFLOW linux 2.6.x-3.x kernel module by <[email protected]> -- 2008-2015.
538546
in kernel jiffies units (which is x/HZ seconds).
539547

540548
promisc=1
541-
- Enable promisc hack. See README.promisc Solution.1 for details.
549+
- Enables promisc hack. See README.promisc Solution 1 for details.
542550

543551
exportcpu=number
544552
- Lock exporter to single CPU. This may be useful to fine control CPU

Diff for: compat.h

+15
Original file line numberDiff line numberDiff line change
@@ -268,4 +268,19 @@ static void *__seq_open_private(struct file *f, struct seq_operations *ops,
268268
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
269269
#endif
270270

271+
#ifndef MPLS_HLEN
272+
#define MPLS_HLEN 4
273+
static inline int eth_p_mpls(__be16 eth_type)
274+
{
275+
return eth_type == htons(ETH_P_MPLS_UC) ||
276+
eth_type == htons(ETH_P_MPLS_MC);
277+
}
278+
#endif
279+
#ifndef MPLS_LS_S_MASK
280+
struct mpls_label {
281+
__be32 entry;
282+
};
283+
#define MPLS_LS_S_MASK 0x00000100
284+
#endif
285+
271286
#endif /* COMPAT_NETFLOW_H */

Diff for: configure

+7-2
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ show_help() {
270270
echo " --enable-sampler enables Flow Sampling"
271271
echo " --enable-sampler=hash enables Hash sampler"
272272
echo " --enable-aggregation enables aggregation rules"
273-
echo " --enable-promisc enables promisc hack"
273+
echo " --enable-promisc enables promisc hack mode"
274+
echo " --promisc-mpls decapsulate MPLS in promisc mode"
274275
echo " --enable-physdev enables physdev reporting"
275276
echo " --enable-physdev-override to override interfaces"
276277
echo " --disable-snmp-agent disables net-snmp agent"
@@ -302,7 +303,8 @@ do
302303
--enable-sampl*hash) KOPTS="$KOPTS -DENABLE_SAMPLER -DSAMPLING_HASH" ;;
303304
--enable-sampl*) KOPTS="$KOPTS -DENABLE_SAMPLER" ;;
304305
--enable-aggr*) KOPTS="$KOPTS -DENABLE_AGGR" ;;
305-
--enable-promi*) KOPTS="$KOPTS -DENABLE_PROMISC" ;;
306+
--enable-promi*) ENABLE_PROMISC=1 ;;
307+
--promisc-mpls) ENABLE_PROMISC=1; PROMISC_MPLS=1 ;;
306308
--enable-snmp-r*) KOPTS="$KOPTS -DENABLE_SNMP" ;;
307309
--enable-physdev) KOPTS="$KOPTS -DENABLE_PHYSDEV" ;;
308310
--enable-physdev-over*) KOPTS="$KOPTS -DENABLE_PHYSDEV_OVER" ;;
@@ -318,6 +320,9 @@ do
318320
esac
319321
done
320322

323+
if [ "$ENABLE_PROMISC" = 1 ]; then KOPTS="$KOPTS -DENABLE_PROMISC"; fi
324+
if [ "$PROMISC_MPLS" = 1 ]; then KOPTS="$KOPTS -DPROMISC_MPLS"; fi
325+
321326
kernel_find_version() {
322327
KHOW=requested
323328
test "$KVERSION" && return 0

Diff for: ipt_NETFLOW.c

+26-2
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,9 @@ static int nf_seq_show(struct seq_file *seq, void *v)
578578
#endif
579579
#ifdef ENABLE_PROMISC
580580
" promisc"
581+
# ifdef PROMISC_MPLS
582+
"+mpls"
583+
# endif
581584
#endif
582585
#ifdef ENABLE_SAMPLER
583586
" samp"
@@ -1302,17 +1305,38 @@ static int promisc_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
13021305
skb_pull(skb, vlan_depth);
13031306

13041307
skb_reset_network_header(skb);
1305-
skb_reset_transport_header(skb);
13061308
skb_reset_mac_len(skb);
13071309
}
1310+
# ifdef PROMISC_MPLS
1311+
if (eth_p_mpls(skb->protocol)) {
1312+
size_t stack_len = 0;
1313+
const struct mpls_label *mpls;
1314+
1315+
do {
1316+
mpls = (struct mpls_label *)(skb->data + stack_len);
1317+
stack_len += MPLS_HLEN;
1318+
if (unlikely(!pskb_may_pull(skb, stack_len)))
1319+
goto drop;
1320+
} while (!(mpls->entry & htonl(MPLS_LS_S_MASK)));
1321+
1322+
skb_pull(skb, stack_len);
1323+
skb_reset_network_header(skb);
13081324

1325+
if (!pskb_may_pull(skb, 1))
1326+
goto drop;
1327+
switch (ip_hdr(skb)->version) {
1328+
case 4: skb->protocol = htons(ETH_P_IP); break;
1329+
case 6: skb->protocol = htons(ETH_P_IPV6); break;
1330+
default: goto drop;
1331+
}
1332+
}
1333+
# endif
13091334
switch (skb->protocol) {
13101335
case htons(ETH_P_IP):
13111336
return promisc4_rcv(skb, dev, pt, orig_dev);
13121337
case htons(ETH_P_IPV6):
13131338
return promisc6_rcv(skb, dev, pt, orig_dev);
13141339
}
1315-
13161340
drop:
13171341
NETFLOW_STAT_INC(pkt_promisc_drop);
13181342
out:

Diff for: testing.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ readarray -t opts <<EOF
3131
--enable-direction
3232
--enable-sampler
3333
--enable-sampler=hash
34-
--enable-promisc
34+
--enable-promisc --promisc-mpls
3535
--enable-physdev
3636
--enable-physdev-override
3737
EOF
3838
if [ "$SHORT" ]; then
39-
opts=("")
39+
opts=("$SHORT")
4040
fi
4141

4242
colorecho() {

0 commit comments

Comments
 (0)