Get in touch:
01524 851 877
07718 896 553

Linux XFRM Framework Selectors

Posted on Apr 17 2008 by Matthew Jakeman

Whilst progressing some code I have been writing I was recently introduced to Linux’s XFRM (transform) framework. I had not heard of this before but it can be a very useful tool for manipulating packets.

The one big downside to XFRM is there is virtually no documentation on it yet. This can make working with it quite tricky. I am documenting what I find out from using it here in the hope that others will find it useful.

The basic idea behind XFRM is that it allows you to select a packet based on a number of factors. These are all defined in /usr/include/linux/xfrm.h in a struct named xfrm_selector as defined below :

struct xfrm_selector
xfrm_address_t daddr;
xfrm_address_t saddr;
__be16 dport;
__be16 dport_mask;
__be16 sport;
__be16 sport_mask;
__u16 family;
__u8 prefixlen_d;
__u8 prefixlen_s;
__u8 proto;
int ifindex;
uid_t user;

Creating a struct of this type and setting the fields such as the source/destination addresses, ports, address masks etc, allows a packet to be selected, based on this criteria, to allow it to be transformed. By passing this information into the kernel using a nlmsghdr struct and the addattr_l() function along with a template (struct xfmr_user_tmpl) describing what action to take on the packet we can alter certain packets however we wish.

This is proving very useful to me in some of my current work and I will continue to post anything I think might be useful to others working in the same area on this blog.


  1. ThePoliteGuy says:

    Thank you, it was very helpful! Now it is 2011 (3 years have passed since you wrote this) but this framework still haven’t been documented …

    So did you had a chance to write something that explains xfrm in more details? Maybe you were able to find some good documentation somewhere else?

    What we are trying to accomplish is that Selector would be able to choose packets by some other means than just source/destination IP/Port.

    • MattJakeman says:

      Hi, unfortunately I was unable to find much more documentation about XFRM when I was using it. What sort of selectors are you wishing to use? From memory the only parameters you are able to use for a selector are the ones specified in this struct.

      It’s likely that it would be easier to write a kernel module for your purposes but it’s hard to tell without more details about what you are trying to accomplish.

      • The PoliteGuy says:

        I would like to implement SAref tracking for IPsec NETKEY stack (it is implemented with XFRM). Currently only KLIPS IPsec stack supports this feature, but that one has scalability problems on multiqueue NICs. So we decided rather to patch NETKEY stack.

        Basically SAref tracking allows you to write your own IP address mapper in linux kernel module, whic is SAref_id+non_unique_natted_ipunique_ip. The SArefId should be stored in SKB. The problem SAref tracking solves is that two IPsec clients with overlapping subnets will be able to connect to the same IPsec server.

      • ThePoliteGuy says:

        In my previous replay some symbols were removed: It should be read like this: “Basically SAref tracking allows you to write your own IP address mapper in linux kernel module: SAref_id+non_unique_natted_ip to unique_ip; and unique_ip to SAref_id+non_unique_natted_ip”

  2. nima0102 says:

    Thanks for sharing your knowledge.
    I am some confused about Netfilter and XFRM framework.
    Can anybody difference between these frameworks?

    Thanks in advance

  3. Hi
    I will appreciate if someone will explain xfrm templates. What are they used for ? Struct xfrm_template

Leave a comment