In Linux, SRv6 policies can be pushed based on the destination address of packets. 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:: 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@xxxxxxxxx> --- net/ipv6/netfilter/ip6t_SEG6.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/net/ipv6/netfilter/ip6t_SEG6.c b/net/ipv6/netfilter/ip6t_SEG6.c index 0adfb98ccaf2..283786cf4126 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; @@ -87,6 +99,7 @@ static int seg6_check(const struct xt_tgchk_param *par) case IP6T_SEG6_GO_NEXT: case IP6T_SEG6_SKIP_NEXT: case IP6T_SEG6_GO_LAST: + case IP6T_SEG6_BSID: return 0; default: return -EOPNOTSUPP; -- 2.11.0