162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef __NET_TC_VLAN_H
762306a36Sopenharmony_ci#define __NET_TC_VLAN_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <net/act_api.h>
1062306a36Sopenharmony_ci#include <linux/tc_act/tc_vlan.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistruct tcf_vlan_params {
1362306a36Sopenharmony_ci	int               tcfv_action;
1462306a36Sopenharmony_ci	unsigned char     tcfv_push_dst[ETH_ALEN];
1562306a36Sopenharmony_ci	unsigned char     tcfv_push_src[ETH_ALEN];
1662306a36Sopenharmony_ci	u16               tcfv_push_vid;
1762306a36Sopenharmony_ci	__be16            tcfv_push_proto;
1862306a36Sopenharmony_ci	u8                tcfv_push_prio;
1962306a36Sopenharmony_ci	bool              tcfv_push_prio_exists;
2062306a36Sopenharmony_ci	struct rcu_head   rcu;
2162306a36Sopenharmony_ci};
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistruct tcf_vlan {
2462306a36Sopenharmony_ci	struct tc_action	common;
2562306a36Sopenharmony_ci	struct tcf_vlan_params __rcu *vlan_p;
2662306a36Sopenharmony_ci};
2762306a36Sopenharmony_ci#define to_vlan(a) ((struct tcf_vlan *)a)
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic inline bool is_tcf_vlan(const struct tc_action *a)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci#ifdef CONFIG_NET_CLS_ACT
3262306a36Sopenharmony_ci	if (a->ops && a->ops->id == TCA_ID_VLAN)
3362306a36Sopenharmony_ci		return true;
3462306a36Sopenharmony_ci#endif
3562306a36Sopenharmony_ci	return false;
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic inline u32 tcf_vlan_action(const struct tc_action *a)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	u32 tcfv_action;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	rcu_read_lock();
4362306a36Sopenharmony_ci	tcfv_action = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_action;
4462306a36Sopenharmony_ci	rcu_read_unlock();
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	return tcfv_action;
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic inline u16 tcf_vlan_push_vid(const struct tc_action *a)
5062306a36Sopenharmony_ci{
5162306a36Sopenharmony_ci	u16 tcfv_push_vid;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	rcu_read_lock();
5462306a36Sopenharmony_ci	tcfv_push_vid = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_vid;
5562306a36Sopenharmony_ci	rcu_read_unlock();
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	return tcfv_push_vid;
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic inline __be16 tcf_vlan_push_proto(const struct tc_action *a)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	__be16 tcfv_push_proto;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	rcu_read_lock();
6562306a36Sopenharmony_ci	tcfv_push_proto = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_proto;
6662306a36Sopenharmony_ci	rcu_read_unlock();
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	return tcfv_push_proto;
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic inline u8 tcf_vlan_push_prio(const struct tc_action *a)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	u8 tcfv_push_prio;
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	rcu_read_lock();
7662306a36Sopenharmony_ci	tcfv_push_prio = rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_prio;
7762306a36Sopenharmony_ci	rcu_read_unlock();
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	return tcfv_push_prio;
8062306a36Sopenharmony_ci}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic inline void tcf_vlan_push_eth(unsigned char *src, unsigned char *dest,
8362306a36Sopenharmony_ci				     const struct tc_action *a)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	rcu_read_lock();
8662306a36Sopenharmony_ci	memcpy(dest, rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_dst, ETH_ALEN);
8762306a36Sopenharmony_ci	memcpy(src, rcu_dereference(to_vlan(a)->vlan_p)->tcfv_push_src, ETH_ALEN);
8862306a36Sopenharmony_ci	rcu_read_unlock();
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#endif /* __NET_TC_VLAN_H */
92