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.

Example:
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 <amsala...@gmail.com>
---
 net/ipv6/netfilter/ip6t_SEG6.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

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;
-- 
2.11.0

Reply via email to