diff mbox series

[nf-next,3/3] netfilter: using ip6tables as L2/L3/L4 classifier for SRv6

Message ID 20180816145143.12963-3-amsalam20@gmail.com
State Changes Requested
Delegated to: Pablo Neira
Headers show
Series [nf-next,1/3] netfilter: export SRH processing functions from seg6local | expand

Commit Message

Ahmed Abdelsalam Aug. 16, 2018, 2:51 p.m. UTC
In Linux, SRv6 policies can be pushed based on
packets destination address.

However for many use-cases, it is needed to push SRv6
policies based on information from L2/L3/L4.

Consider a use-case where you want to push SRv6 policies based on
the application layer protocol (HTTP/DNS), which requires being able
to match the destination port of a packet.

In this patch, we use iptables a classifier for SRv6, hence we benefit
from all of its matching capabilities.

We added a new action to the SEG6 target, named "bind-sid", that takes
the BSID and the SID table as arguments.

Each packet that matches an iptables rule with SEG6 target that has the
bind-sid action, will go through the SRv6 policies configured for that BSID.

We have an SRv6 policy configured in Linux as follows:
ip -6 route add A99::1 encap seg6 mode encap segs F1::,F2::,F3:: dev eth1

We can steer traffic through this SRv6 policy using the matching power of
iptables firewall as follows:

ip6atbles -t raw -I PREROUTING -s <saddr> -d <daddr> \
-p <proto> --sport <src_port> --dport <dst_port> \
-j SEG6 --seg6-action bind-sid --bsid A99::1 --bsid-tbl 0

This new SEG6 action should perfectly address all use-cases that require
pushing SRv6 policies based information from Layer3/Layer4.

Signed-off-by: Ahmed Abdelsalam <amsalam20@gmail.com>
 net/ipv6/netfilter/ip6t_SEG6.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
diff mbox series


diff --git a/net/ipv6/netfilter/ip6t_SEG6.c b/net/ipv6/netfilter/ip6t_SEG6.c
index 03b5f1a1c8bf..0f6aec7ebefe 100644
--- a/net/ipv6/netfilter/ip6t_SEG6.c
+++ b/net/ipv6/netfilter/ip6t_SEG6.c
@@ -25,6 +25,14 @@ 
 #include <net/seg6.h>
 #include <net/ip6_route.h>
+static int seg6_bsid(struct sk_buff *skb, struct in6_addr bsid,
+		     u32 tbl)
+	seg6_lookup_nexthop(skb, &bsid, tbl);
+	dst_input(skb);
+	return NF_STOLEN;
 static int seg6_go_next(struct sk_buff *skb, struct ipv6_sr_hdr *srh)
 	if (srh->segments_left == 0)
@@ -63,6 +71,10 @@  seg6_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 	struct ipv6_sr_hdr *srh;
 	const struct ip6t_seg6_info *seg6 = par->targinfo;
+	/* bind-sid action doesn't require packets with SRH */
+	if (seg6->action == IP6T_SEG6_BSID)
+		return seg6_bsid(skb, seg6->bsid, seg6->tbl);
 	srh = seg6_get_srh(skb);
 	if (!srh)
 		return NF_DROP;