Skip to content

Commit

Permalink
Implements #36: Decapsulate MPLS in promisc mode.
Browse files Browse the repository at this point in the history
./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.
  • Loading branch information
aabc committed Apr 9, 2015
1 parent 57d3cbf commit 9d1ea8e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 9 deletions.
14 changes: 11 additions & 3 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ ipt_NETFLOW linux 2.6.x-3.x kernel module by <[email protected]> -- 2008-2015.
* SNMP-index translation rules, let convert meaningless and unstable
interface indexes (ifIndex) to more meaningful numbering scheme.

* Easy support for catching mirrored traffic with promisc option.
* Easy support for catching mirrored traffic with promisc option. Which is
also supporting optional MPLS decapsulation.


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

--enable-physdev

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

--enable-promisc
Enables capturing of promiscuous packets into raw/PREROUTING chain.
See README.promisc Solution 1 for usage details and example.

--promisc-mpls
Enables MPLS label stack decapsulation for promiscuous packets. (For
IPv4 and IPv6 packets only).


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

promisc=1
- Enable promisc hack. See README.promisc Solution.1 for details.
- Enables promisc hack. See README.promisc Solution 1 for details.

exportcpu=number
- Lock exporter to single CPU. This may be useful to fine control CPU
Expand Down
15 changes: 15 additions & 0 deletions compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,19 @@ static void *__seq_open_private(struct file *f, struct seq_operations *ops,
#define __get_cpu_var(var) (*this_cpu_ptr(&(var)))
#endif

#ifndef MPLS_HLEN
#define MPLS_HLEN 4
static inline int eth_p_mpls(__be16 eth_type)
{
return eth_type == htons(ETH_P_MPLS_UC) ||
eth_type == htons(ETH_P_MPLS_MC);
}
#endif
#ifndef MPLS_LS_S_MASK
struct mpls_label {
__be32 entry;
};
#define MPLS_LS_S_MASK 0x00000100
#endif

#endif /* COMPAT_NETFLOW_H */
9 changes: 7 additions & 2 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ show_help() {
echo " --enable-sampler enables Flow Sampling"
echo " --enable-sampler=hash enables Hash sampler"
echo " --enable-aggregation enables aggregation rules"
echo " --enable-promisc enables promisc hack"
echo " --enable-promisc enables promisc hack mode"
echo " --promisc-mpls decapsulate MPLS in promisc mode"
echo " --enable-physdev enables physdev reporting"
echo " --enable-physdev-override to override interfaces"
echo " --disable-snmp-agent disables net-snmp agent"
Expand Down Expand Up @@ -302,7 +303,8 @@ do
--enable-sampl*hash) KOPTS="$KOPTS -DENABLE_SAMPLER -DSAMPLING_HASH" ;;
--enable-sampl*) KOPTS="$KOPTS -DENABLE_SAMPLER" ;;
--enable-aggr*) KOPTS="$KOPTS -DENABLE_AGGR" ;;
--enable-promi*) KOPTS="$KOPTS -DENABLE_PROMISC" ;;
--enable-promi*) ENABLE_PROMISC=1 ;;
--promisc-mpls) ENABLE_PROMISC=1; PROMISC_MPLS=1 ;;
--enable-snmp-r*) KOPTS="$KOPTS -DENABLE_SNMP" ;;
--enable-physdev) KOPTS="$KOPTS -DENABLE_PHYSDEV" ;;
--enable-physdev-over*) KOPTS="$KOPTS -DENABLE_PHYSDEV_OVER" ;;
Expand All @@ -318,6 +320,9 @@ do
esac
done

if [ "$ENABLE_PROMISC" = 1 ]; then KOPTS="$KOPTS -DENABLE_PROMISC"; fi
if [ "$PROMISC_MPLS" = 1 ]; then KOPTS="$KOPTS -DPROMISC_MPLS"; fi

kernel_find_version() {
KHOW=requested
test "$KVERSION" && return 0
Expand Down
28 changes: 26 additions & 2 deletions ipt_NETFLOW.c
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,9 @@ static int nf_seq_show(struct seq_file *seq, void *v)
#endif
#ifdef ENABLE_PROMISC
" promisc"
# ifdef PROMISC_MPLS
"+mpls"
# endif
#endif
#ifdef ENABLE_SAMPLER
" samp"
Expand Down Expand Up @@ -1302,17 +1305,38 @@ static int promisc_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
skb_pull(skb, vlan_depth);

skb_reset_network_header(skb);
skb_reset_transport_header(skb);
skb_reset_mac_len(skb);
}
# ifdef PROMISC_MPLS
if (eth_p_mpls(skb->protocol)) {
size_t stack_len = 0;
const struct mpls_label *mpls;

do {
mpls = (struct mpls_label *)(skb->data + stack_len);
stack_len += MPLS_HLEN;
if (unlikely(!pskb_may_pull(skb, stack_len)))
goto drop;
} while (!(mpls->entry & htonl(MPLS_LS_S_MASK)));

skb_pull(stack_len);
skb_reset_network_header(skb);

if (!pskb_may_pull(skb, 1))
goto drop;
switch (ip_hdr(skb)->version) {
case 4: skb->protocol = htons(ETH_P_IP); break;
case 6: skb->protocol = htons(ETH_P_IPV6); break;
default: goto drop;
}
}
# endif
switch (skb->protocol) {
case htons(ETH_P_IP):
return promisc4_rcv(skb, dev, pt, orig_dev);
case htons(ETH_P_IPV6):
return promisc6_rcv(skb, dev, pt, orig_dev);
}

drop:
NETFLOW_STAT_INC(pkt_promisc_drop);
out:
Expand Down
4 changes: 2 additions & 2 deletions testing.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ readarray -t opts <<EOF
--enable-direction
--enable-sampler
--enable-sampler=hash
--enable-promisc
--enable-promisc --promisc-mpls
--enable-physdev
--enable-physdev-override
EOF
if [ "$SHORT" ]; then
opts=("")
opts=("$SHORT")
fi

colorecho() {
Expand Down

0 comments on commit 9d1ea8e

Please sign in to comment.