Skip to content

Commit

Permalink
xfrm: use gre key as flow upper protocol info
Browse files Browse the repository at this point in the history
The GRE Key field is intended to be used for identifying an individual
traffic flow within a tunnel. It is useful to be able to have XFRM
policy selector matches to have different policies for different
GRE tunnels.

Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Timo Teräs authored and David S. Miller committed Nov 15, 2010
1 parent e1f2d8c commit cc9ff19
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 5 deletions.
2 changes: 2 additions & 0 deletions include/net/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct flowi {
} dnports;

__be32 spi;
__be32 gre_key;

struct {
__u8 type;
Expand All @@ -78,6 +79,7 @@ struct flowi {
#define fl_icmp_code uli_u.icmpt.code
#define fl_ipsec_spi uli_u.spi
#define fl_mh_type uli_u.mht.type
#define fl_gre_key uli_u.gre_key
__u32 secid; /* used by xfrm; see secid.txt */
} __attribute__((__aligned__(BITS_PER_LONG/8)));

Expand Down
6 changes: 6 additions & 0 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,9 @@ __be16 xfrm_flowi_sport(struct flowi *fl)
case IPPROTO_MH:
port = htons(fl->fl_mh_type);
break;
case IPPROTO_GRE:
port = htonl(fl->fl_gre_key) >> 16;
break;
default:
port = 0; /*XXX*/
}
Expand All @@ -826,6 +829,9 @@ __be16 xfrm_flowi_dport(struct flowi *fl)
case IPPROTO_ICMPV6:
port = htons(fl->fl_icmp_code);
break;
case IPPROTO_GRE:
port = htonl(fl->fl_gre_key) & 0xffff;
break;
default:
port = 0; /*XXX*/
}
Expand Down
12 changes: 7 additions & 5 deletions net/ipv4/ip_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,9 +779,9 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
.tos = RT_TOS(tos)
}
},
.proto = IPPROTO_GRE
}
;
.proto = IPPROTO_GRE,
.fl_gre_key = tunnel->parms.o_key
};
if (ip_route_output_key(dev_net(dev), &rt, &fl)) {
dev->stats.tx_carrier_errors++;
goto tx_error;
Expand Down Expand Up @@ -958,7 +958,8 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
.tos = RT_TOS(iph->tos)
}
},
.proto = IPPROTO_GRE
.proto = IPPROTO_GRE,
.fl_gre_key = tunnel->parms.o_key
};
struct rtable *rt;

Expand Down Expand Up @@ -1223,7 +1224,8 @@ static int ipgre_open(struct net_device *dev)
.tos = RT_TOS(t->parms.iph.tos)
}
},
.proto = IPPROTO_GRE
.proto = IPPROTO_GRE,
.fl_gre_key = t->parms.o_key
};
struct rtable *rt;

Expand Down
15 changes: 15 additions & 0 deletions net/ipv4/xfrm4_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/inetdevice.h>
#include <linux/if_tunnel.h>
#include <net/dst.h>
#include <net/xfrm.h>
#include <net/ip.h>
Expand Down Expand Up @@ -154,6 +155,20 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
}
break;

case IPPROTO_GRE:
if (pskb_may_pull(skb, xprth + 12 - skb->data)) {
__be16 *greflags = (__be16 *)xprth;
__be32 *gre_hdr = (__be32 *)xprth;

if (greflags[0] & GRE_KEY) {
if (greflags[0] & GRE_CSUM)
gre_hdr++;
fl->fl_gre_key = gre_hdr[1];
}
}
break;

default:
fl->fl_ipsec_spi = 0;
break;
Expand Down

0 comments on commit cc9ff19

Please sign in to comment.