diff options
| author | Craig Gallek <kraig@google.com> | 2017-04-19 12:30:53 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-04-21 13:21:30 -0400 |
| commit | 0a473b82cb23e7a35c4be6e9765c8487a65e8f55 (patch) | |
| tree | 5568a1f040800160b0d9a9722d39f59403273199 /net/ipv6/ip6_gre.c | |
| parent | 8e6c1812e632ae3b54a1a9da759cad762f633e11 (diff) | |
ip6_tunnel: Allow policy-based routing through tunnels
This feature allows the administrator to set an fwmark for
packets traversing a tunnel. This allows the use of independent
routing tables for tunneled packets without the use of iptables.
Signed-off-by: Craig Gallek <kraig@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_gre.c')
| -rw-r--r-- | net/ipv6/ip6_gre.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 6fcb7cb49bb2..8d128ba79b66 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
| @@ -544,6 +544,8 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev) | |||
| 544 | & IPV6_TCLASS_MASK; | 544 | & IPV6_TCLASS_MASK; |
| 545 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) | 545 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) |
| 546 | fl6.flowi6_mark = skb->mark; | 546 | fl6.flowi6_mark = skb->mark; |
| 547 | else | ||
| 548 | fl6.flowi6_mark = t->parms.fwmark; | ||
| 547 | 549 | ||
| 548 | fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); | 550 | fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); |
| 549 | 551 | ||
| @@ -603,6 +605,8 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev) | |||
| 603 | fl6.flowlabel |= ip6_flowlabel(ipv6h); | 605 | fl6.flowlabel |= ip6_flowlabel(ipv6h); |
| 604 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) | 606 | if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK) |
| 605 | fl6.flowi6_mark = skb->mark; | 607 | fl6.flowi6_mark = skb->mark; |
| 608 | else | ||
| 609 | fl6.flowi6_mark = t->parms.fwmark; | ||
| 606 | 610 | ||
| 607 | fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); | 611 | fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); |
| 608 | 612 | ||
| @@ -780,6 +784,7 @@ static int ip6gre_tnl_change(struct ip6_tnl *t, | |||
| 780 | t->parms.o_key = p->o_key; | 784 | t->parms.o_key = p->o_key; |
| 781 | t->parms.i_flags = p->i_flags; | 785 | t->parms.i_flags = p->i_flags; |
| 782 | t->parms.o_flags = p->o_flags; | 786 | t->parms.o_flags = p->o_flags; |
| 787 | t->parms.fwmark = p->fwmark; | ||
| 783 | dst_cache_reset(&t->dst_cache); | 788 | dst_cache_reset(&t->dst_cache); |
| 784 | ip6gre_tnl_link_config(t, set_mtu); | 789 | ip6gre_tnl_link_config(t, set_mtu); |
| 785 | return 0; | 790 | return 0; |
| @@ -1249,6 +1254,9 @@ static void ip6gre_netlink_parms(struct nlattr *data[], | |||
| 1249 | 1254 | ||
| 1250 | if (data[IFLA_GRE_FLAGS]) | 1255 | if (data[IFLA_GRE_FLAGS]) |
| 1251 | parms->flags = nla_get_u32(data[IFLA_GRE_FLAGS]); | 1256 | parms->flags = nla_get_u32(data[IFLA_GRE_FLAGS]); |
| 1257 | |||
| 1258 | if (data[IFLA_GRE_FWMARK]) | ||
| 1259 | parms->fwmark = nla_get_u32(data[IFLA_GRE_FWMARK]); | ||
| 1252 | } | 1260 | } |
| 1253 | 1261 | ||
| 1254 | static int ip6gre_tap_init(struct net_device *dev) | 1262 | static int ip6gre_tap_init(struct net_device *dev) |
| @@ -1470,6 +1478,8 @@ static size_t ip6gre_get_size(const struct net_device *dev) | |||
| 1470 | nla_total_size(2) + | 1478 | nla_total_size(2) + |
| 1471 | /* IFLA_GRE_ENCAP_DPORT */ | 1479 | /* IFLA_GRE_ENCAP_DPORT */ |
| 1472 | nla_total_size(2) + | 1480 | nla_total_size(2) + |
| 1481 | /* IFLA_GRE_FWMARK */ | ||
| 1482 | nla_total_size(4) + | ||
| 1473 | 0; | 1483 | 0; |
| 1474 | } | 1484 | } |
| 1475 | 1485 | ||
| @@ -1490,7 +1500,8 @@ static int ip6gre_fill_info(struct sk_buff *skb, const struct net_device *dev) | |||
| 1490 | nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || | 1500 | nla_put_u8(skb, IFLA_GRE_TTL, p->hop_limit) || |
| 1491 | nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || | 1501 | nla_put_u8(skb, IFLA_GRE_ENCAP_LIMIT, p->encap_limit) || |
| 1492 | nla_put_be32(skb, IFLA_GRE_FLOWINFO, p->flowinfo) || | 1502 | nla_put_be32(skb, IFLA_GRE_FLOWINFO, p->flowinfo) || |
| 1493 | nla_put_u32(skb, IFLA_GRE_FLAGS, p->flags)) | 1503 | nla_put_u32(skb, IFLA_GRE_FLAGS, p->flags) || |
| 1504 | nla_put_u32(skb, IFLA_GRE_FWMARK, p->fwmark)) | ||
| 1494 | goto nla_put_failure; | 1505 | goto nla_put_failure; |
| 1495 | 1506 | ||
| 1496 | if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE, | 1507 | if (nla_put_u16(skb, IFLA_GRE_ENCAP_TYPE, |
| @@ -1525,6 +1536,7 @@ static const struct nla_policy ip6gre_policy[IFLA_GRE_MAX + 1] = { | |||
| 1525 | [IFLA_GRE_ENCAP_FLAGS] = { .type = NLA_U16 }, | 1536 | [IFLA_GRE_ENCAP_FLAGS] = { .type = NLA_U16 }, |
| 1526 | [IFLA_GRE_ENCAP_SPORT] = { .type = NLA_U16 }, | 1537 | [IFLA_GRE_ENCAP_SPORT] = { .type = NLA_U16 }, |
| 1527 | [IFLA_GRE_ENCAP_DPORT] = { .type = NLA_U16 }, | 1538 | [IFLA_GRE_ENCAP_DPORT] = { .type = NLA_U16 }, |
| 1539 | [IFLA_GRE_FWMARK] = { .type = NLA_U32 }, | ||
| 1528 | }; | 1540 | }; |
| 1529 | 1541 | ||
| 1530 | static struct rtnl_link_ops ip6gre_link_ops __read_mostly = { | 1542 | static struct rtnl_link_ops ip6gre_link_ops __read_mostly = { |
