Skip to content

Commit

Permalink
Merge branch 'tc-tunnel-ttl-tos'
Browse files Browse the repository at this point in the history
Or Gerlitz says

====================
set/match the tos/ttl fields of TC based IP tunnels

This series comes to address the case to set (encap) and match (decap)
also the tos and ttl fields of TC based IP tunnels.

Example encap (1st one) and decap (2nd) that use the new fields

tc filter add dev eth0_0 protocol ip parent ffff: prio 10 flower \
	src_mac e4:11:22:33:44:50 dst_mac e4:11:22:33:44:70  \
	action tunnel_key set src_ip 192.168.10.1 dst_ip 192.168.10.2 id 100 dst_port 4789 tos 0x30 \
	action mirred egress redirect dev vxlan_sys_4789

tc filter add dev vxlan_sys_4789 protocol ip parent ffff: prio 10 flower \
	enc_src_ip 192.168.10.2 enc_dst_ip 192.168.10.1 enc_key_id 100 enc_dst_port 4789 enc_tos 0x30 \
	src_mac e4:11:22:33:44:70 dst_mac e4:11:22:33:44:50 \
	action tunnel_key unset \
	action mirred egress redirect dev eth0_0
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 20, 2018
2 parents 3bc950c + 0e2c17b commit 57dc2bf
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 19 deletions.
2 changes: 1 addition & 1 deletion include/net/flow_dissector.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_flow_vlan */

FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
FLOW_DISSECTOR_KEY_MAX,
};

Expand Down
5 changes: 5 additions & 0 deletions include/uapi/linux/pkt_cls.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,11 @@ enum {
TCA_FLOWER_KEY_CVLAN_PRIO, /* u8 */
TCA_FLOWER_KEY_CVLAN_ETH_TYPE, /* be16 */

TCA_FLOWER_KEY_ENC_IP_TOS, /* u8 */
TCA_FLOWER_KEY_ENC_IP_TOS_MASK, /* u8 */
TCA_FLOWER_KEY_ENC_IP_TTL, /* u8 */
TCA_FLOWER_KEY_ENC_IP_TTL_MASK, /* u8 */

__TCA_FLOWER_MAX,
};

Expand Down
2 changes: 2 additions & 0 deletions include/uapi/linux/tc_act/tc_tunnel_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ enum {
TCA_TUNNEL_KEY_ENC_OPTS, /* Nested TCA_TUNNEL_KEY_ENC_OPTS_
* attributes
*/
TCA_TUNNEL_KEY_ENC_TOS, /* u8 */
TCA_TUNNEL_KEY_ENC_TTL, /* u8 */
__TCA_TUNNEL_KEY_MAX,
};

Expand Down
14 changes: 13 additions & 1 deletion net/core/flow_dissector.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
!dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_CONTROL) &&
!dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_PORTS))
FLOW_DISSECTOR_KEY_ENC_PORTS) &&
!dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_IP))
return;

info = skb_tunnel_info(skb);
Expand Down Expand Up @@ -212,6 +214,16 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
tp->src = key->tp_src;
tp->dst = key->tp_dst;
}

if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_IP)) {
struct flow_dissector_key_ip *ip;

ip = skb_flow_dissector_target(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_IP,
target_container);
ip->tos = key->tos;
ip->ttl = key->ttl;
}
}
EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);

Expand Down
20 changes: 18 additions & 2 deletions net/sched/act_tunnel_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
[TCA_TUNNEL_KEY_ENC_DST_PORT] = {.type = NLA_U16},
[TCA_TUNNEL_KEY_NO_CSUM] = { .type = NLA_U8 },
[TCA_TUNNEL_KEY_ENC_OPTS] = { .type = NLA_NESTED },
[TCA_TUNNEL_KEY_ENC_TOS] = { .type = NLA_U8 },
[TCA_TUNNEL_KEY_ENC_TTL] = { .type = NLA_U8 },
};

static int tunnel_key_init(struct net *net, struct nlattr *nla,
Expand All @@ -216,6 +218,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
int opts_len = 0;
__be64 key_id;
__be16 flags;
u8 tos, ttl;
int ret = 0;
int err;

Expand Down Expand Up @@ -273,6 +276,13 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
}
}

tos = 0;
if (tb[TCA_TUNNEL_KEY_ENC_TOS])
tos = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_TOS]);
ttl = 0;
if (tb[TCA_TUNNEL_KEY_ENC_TTL])
ttl = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_TTL]);

if (tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC] &&
tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]) {
__be32 saddr;
Expand All @@ -281,7 +291,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
saddr = nla_get_in_addr(tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC]);
daddr = nla_get_in_addr(tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]);

metadata = __ip_tun_set_dst(saddr, daddr, 0, 0,
metadata = __ip_tun_set_dst(saddr, daddr, tos, ttl,
dst_port, flags,
key_id, opts_len);
} else if (tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC] &&
Expand All @@ -292,7 +302,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
saddr = nla_get_in6_addr(tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC]);
daddr = nla_get_in6_addr(tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]);

metadata = __ipv6_tun_set_dst(&saddr, &daddr, 0, 0, dst_port,
metadata = __ipv6_tun_set_dst(&saddr, &daddr, tos, ttl, dst_port,
0, flags,
key_id, 0);
} else {
Expand Down Expand Up @@ -504,6 +514,12 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
!(key->tun_flags & TUNNEL_CSUM)) ||
tunnel_key_opts_dump(skb, info))
goto nla_put_failure;

if (key->tos && nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_TOS, key->tos))
goto nla_put_failure;

if (key->ttl && nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_TTL, key->ttl))
goto nla_put_failure;
}

tcf_tm_dump(&tm, &t->tcf_tm);
Expand Down
43 changes: 28 additions & 15 deletions net/sched/cls_flower.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct fl_flow_key {
struct flow_dissector_key_mpls mpls;
struct flow_dissector_key_tcp tcp;
struct flow_dissector_key_ip ip;
struct flow_dissector_key_ip enc_ip;
} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */

struct fl_flow_mask_range {
Expand Down Expand Up @@ -453,6 +454,10 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
[TCA_FLOWER_KEY_CVLAN_ID] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_CVLAN_PRIO] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_CVLAN_ETH_TYPE] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_ENC_IP_TOS] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_ENC_IP_TOS_MASK] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_ENC_IP_TTL] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_ENC_IP_TTL_MASK] = { .type = NLA_U8 },
};

static void fl_set_key_val(struct nlattr **tb,
Expand Down Expand Up @@ -561,17 +566,17 @@ static int fl_set_key_flags(struct nlattr **tb,
return 0;
}

static void fl_set_key_ip(struct nlattr **tb,
static void fl_set_key_ip(struct nlattr **tb, bool encap,
struct flow_dissector_key_ip *key,
struct flow_dissector_key_ip *mask)
{
fl_set_key_val(tb, &key->tos, TCA_FLOWER_KEY_IP_TOS,
&mask->tos, TCA_FLOWER_KEY_IP_TOS_MASK,
sizeof(key->tos));
int tos_key = encap ? TCA_FLOWER_KEY_ENC_IP_TOS : TCA_FLOWER_KEY_IP_TOS;
int ttl_key = encap ? TCA_FLOWER_KEY_ENC_IP_TTL : TCA_FLOWER_KEY_IP_TTL;
int tos_mask = encap ? TCA_FLOWER_KEY_ENC_IP_TOS_MASK : TCA_FLOWER_KEY_IP_TOS_MASK;
int ttl_mask = encap ? TCA_FLOWER_KEY_ENC_IP_TTL_MASK : TCA_FLOWER_KEY_IP_TTL_MASK;

fl_set_key_val(tb, &key->ttl, TCA_FLOWER_KEY_IP_TTL,
&mask->ttl, TCA_FLOWER_KEY_IP_TTL_MASK,
sizeof(key->ttl));
fl_set_key_val(tb, &key->tos, tos_key, &mask->tos, tos_mask, sizeof(key->tos));
fl_set_key_val(tb, &key->ttl, ttl_key, &mask->ttl, ttl_mask, sizeof(key->ttl));
}

static int fl_set_key(struct net *net, struct nlattr **tb,
Expand Down Expand Up @@ -633,7 +638,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
fl_set_key_val(tb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
&mask->basic.ip_proto, TCA_FLOWER_UNSPEC,
sizeof(key->basic.ip_proto));
fl_set_key_ip(tb, &key->ip, &mask->ip);
fl_set_key_ip(tb, false, &key->ip, &mask->ip);
}

if (tb[TCA_FLOWER_KEY_IPV4_SRC] || tb[TCA_FLOWER_KEY_IPV4_DST]) {
Expand Down Expand Up @@ -768,6 +773,8 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
&mask->enc_tp.dst, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,
sizeof(key->enc_tp.dst));

fl_set_key_ip(tb, true, &key->enc_ip, &mask->enc_ip);

if (tb[TCA_FLOWER_KEY_FLAGS])
ret = fl_set_key_flags(tb, &key->control.flags, &mask->control.flags);

Expand Down Expand Up @@ -860,6 +867,8 @@ static void fl_init_dissector(struct fl_flow_mask *mask)
enc_control);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_ENC_PORTS, enc_tp);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_ENC_IP, enc_ip);

skb_flow_dissector_init(&mask->dissector, keys, cnt);
}
Expand Down Expand Up @@ -1208,14 +1217,17 @@ static int fl_dump_key_mpls(struct sk_buff *skb,
return 0;
}

static int fl_dump_key_ip(struct sk_buff *skb,
static int fl_dump_key_ip(struct sk_buff *skb, bool encap,
struct flow_dissector_key_ip *key,
struct flow_dissector_key_ip *mask)
{
if (fl_dump_key_val(skb, &key->tos, TCA_FLOWER_KEY_IP_TOS, &mask->tos,
TCA_FLOWER_KEY_IP_TOS_MASK, sizeof(key->tos)) ||
fl_dump_key_val(skb, &key->ttl, TCA_FLOWER_KEY_IP_TTL, &mask->ttl,
TCA_FLOWER_KEY_IP_TTL_MASK, sizeof(key->ttl)))
int tos_key = encap ? TCA_FLOWER_KEY_ENC_IP_TOS : TCA_FLOWER_KEY_IP_TOS;
int ttl_key = encap ? TCA_FLOWER_KEY_ENC_IP_TTL : TCA_FLOWER_KEY_IP_TTL;
int tos_mask = encap ? TCA_FLOWER_KEY_ENC_IP_TOS_MASK : TCA_FLOWER_KEY_IP_TOS_MASK;
int ttl_mask = encap ? TCA_FLOWER_KEY_ENC_IP_TTL_MASK : TCA_FLOWER_KEY_IP_TTL_MASK;

if (fl_dump_key_val(skb, &key->tos, tos_key, &mask->tos, tos_mask, sizeof(key->tos)) ||
fl_dump_key_val(skb, &key->ttl, ttl_key, &mask->ttl, ttl_mask, sizeof(key->ttl)))
return -1;

return 0;
Expand Down Expand Up @@ -1361,7 +1373,7 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh,
(fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
&mask->basic.ip_proto, TCA_FLOWER_UNSPEC,
sizeof(key->basic.ip_proto)) ||
fl_dump_key_ip(skb, &key->ip, &mask->ip)))
fl_dump_key_ip(skb, false, &key->ip, &mask->ip)))
goto nla_put_failure;

if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS &&
Expand Down Expand Up @@ -1486,7 +1498,8 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh,
TCA_FLOWER_KEY_ENC_UDP_DST_PORT,
&mask->enc_tp.dst,
TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,
sizeof(key->enc_tp.dst)))
sizeof(key->enc_tp.dst)) ||
fl_dump_key_ip(skb, true, &key->enc_ip, &mask->enc_ip))
goto nla_put_failure;

if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags))
Expand Down

0 comments on commit 57dc2bf

Please sign in to comment.