18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/* Copyright (C) 2007-2020  B.A.T.M.A.N. contributors:
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Marek Lindner, Simon Wunderlich
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_
88c2ecf20Sopenharmony_ci#define _NET_BATMAN_ADV_HARD_INTERFACE_H_
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "main.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/compiler.h>
138c2ecf20Sopenharmony_ci#include <linux/kref.h>
148c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
158c2ecf20Sopenharmony_ci#include <linux/notifier.h>
168c2ecf20Sopenharmony_ci#include <linux/rcupdate.h>
178c2ecf20Sopenharmony_ci#include <linux/stddef.h>
188c2ecf20Sopenharmony_ci#include <linux/types.h>
198c2ecf20Sopenharmony_ci#include <net/net_namespace.h>
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/**
228c2ecf20Sopenharmony_ci * enum batadv_hard_if_state - State of a hard interface
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_cienum batadv_hard_if_state {
258c2ecf20Sopenharmony_ci	/**
268c2ecf20Sopenharmony_ci	 * @BATADV_IF_NOT_IN_USE: interface is not used as slave interface of a
278c2ecf20Sopenharmony_ci	 * batman-adv soft interface
288c2ecf20Sopenharmony_ci	 */
298c2ecf20Sopenharmony_ci	BATADV_IF_NOT_IN_USE,
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	/**
328c2ecf20Sopenharmony_ci	 * @BATADV_IF_TO_BE_REMOVED: interface will be removed from soft
338c2ecf20Sopenharmony_ci	 * interface
348c2ecf20Sopenharmony_ci	 */
358c2ecf20Sopenharmony_ci	BATADV_IF_TO_BE_REMOVED,
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	/** @BATADV_IF_INACTIVE: interface is deactivated */
388c2ecf20Sopenharmony_ci	BATADV_IF_INACTIVE,
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	/** @BATADV_IF_ACTIVE: interface is used */
418c2ecf20Sopenharmony_ci	BATADV_IF_ACTIVE,
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	/** @BATADV_IF_TO_BE_ACTIVATED: interface is getting activated */
448c2ecf20Sopenharmony_ci	BATADV_IF_TO_BE_ACTIVATED,
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	/**
478c2ecf20Sopenharmony_ci	 * @BATADV_IF_I_WANT_YOU: interface is queued up (using sysfs) for being
488c2ecf20Sopenharmony_ci	 * added as slave interface of a batman-adv soft interface
498c2ecf20Sopenharmony_ci	 */
508c2ecf20Sopenharmony_ci	BATADV_IF_I_WANT_YOU,
518c2ecf20Sopenharmony_ci};
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/**
548c2ecf20Sopenharmony_ci * enum batadv_hard_if_bcast - broadcast avoidance options
558c2ecf20Sopenharmony_ci */
568c2ecf20Sopenharmony_cienum batadv_hard_if_bcast {
578c2ecf20Sopenharmony_ci	/** @BATADV_HARDIF_BCAST_OK: Do broadcast on according hard interface */
588c2ecf20Sopenharmony_ci	BATADV_HARDIF_BCAST_OK = 0,
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	/**
618c2ecf20Sopenharmony_ci	 * @BATADV_HARDIF_BCAST_NORECIPIENT: Broadcast not needed, there is no
628c2ecf20Sopenharmony_ci	 *  recipient
638c2ecf20Sopenharmony_ci	 */
648c2ecf20Sopenharmony_ci	BATADV_HARDIF_BCAST_NORECIPIENT,
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	/**
678c2ecf20Sopenharmony_ci	 * @BATADV_HARDIF_BCAST_DUPFWD: There is just the neighbor we got it
688c2ecf20Sopenharmony_ci	 *  from
698c2ecf20Sopenharmony_ci	 */
708c2ecf20Sopenharmony_ci	BATADV_HARDIF_BCAST_DUPFWD,
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	/** @BATADV_HARDIF_BCAST_DUPORIG: There is just the originator */
738c2ecf20Sopenharmony_ci	BATADV_HARDIF_BCAST_DUPORIG,
748c2ecf20Sopenharmony_ci};
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci/**
778c2ecf20Sopenharmony_ci * enum batadv_hard_if_cleanup - Cleanup modi for soft_iface after slave removal
788c2ecf20Sopenharmony_ci */
798c2ecf20Sopenharmony_cienum batadv_hard_if_cleanup {
808c2ecf20Sopenharmony_ci	/**
818c2ecf20Sopenharmony_ci	 * @BATADV_IF_CLEANUP_KEEP: Don't automatically delete soft-interface
828c2ecf20Sopenharmony_ci	 */
838c2ecf20Sopenharmony_ci	BATADV_IF_CLEANUP_KEEP,
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	/**
868c2ecf20Sopenharmony_ci	 * @BATADV_IF_CLEANUP_AUTO: Delete soft-interface after last slave was
878c2ecf20Sopenharmony_ci	 *  removed
888c2ecf20Sopenharmony_ci	 */
898c2ecf20Sopenharmony_ci	BATADV_IF_CLEANUP_AUTO,
908c2ecf20Sopenharmony_ci};
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciextern struct notifier_block batadv_hard_if_notifier;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistruct net_device *batadv_get_real_netdev(struct net_device *net_device);
958c2ecf20Sopenharmony_cibool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface);
968c2ecf20Sopenharmony_cibool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface);
978c2ecf20Sopenharmony_cistruct batadv_hard_iface*
988c2ecf20Sopenharmony_cibatadv_hardif_get_by_netdev(const struct net_device *net_dev);
998c2ecf20Sopenharmony_ciint batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
1008c2ecf20Sopenharmony_ci				   struct net *net, const char *iface_name);
1018c2ecf20Sopenharmony_civoid batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
1028c2ecf20Sopenharmony_ci				     enum batadv_hard_if_cleanup autodel);
1038c2ecf20Sopenharmony_ciint batadv_hardif_min_mtu(struct net_device *soft_iface);
1048c2ecf20Sopenharmony_civoid batadv_update_min_mtu(struct net_device *soft_iface);
1058c2ecf20Sopenharmony_civoid batadv_hardif_release(struct kref *ref);
1068c2ecf20Sopenharmony_ciint batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
1078c2ecf20Sopenharmony_ci			       u8 *orig_addr, u8 *orig_neigh);
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci/**
1108c2ecf20Sopenharmony_ci * batadv_hardif_put() - decrement the hard interface refcounter and possibly
1118c2ecf20Sopenharmony_ci *  release it
1128c2ecf20Sopenharmony_ci * @hard_iface: the hard interface to free
1138c2ecf20Sopenharmony_ci */
1148c2ecf20Sopenharmony_cistatic inline void batadv_hardif_put(struct batadv_hard_iface *hard_iface)
1158c2ecf20Sopenharmony_ci{
1168c2ecf20Sopenharmony_ci	if (!hard_iface)
1178c2ecf20Sopenharmony_ci		return;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	kref_put(&hard_iface->refcount, batadv_hardif_release);
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci/**
1238c2ecf20Sopenharmony_ci * batadv_primary_if_get_selected() - Get reference to primary interface
1248c2ecf20Sopenharmony_ci * @bat_priv: the bat priv with all the soft interface information
1258c2ecf20Sopenharmony_ci *
1268c2ecf20Sopenharmony_ci * Return: primary interface (with increased refcnt), otherwise NULL
1278c2ecf20Sopenharmony_ci */
1288c2ecf20Sopenharmony_cistatic inline struct batadv_hard_iface *
1298c2ecf20Sopenharmony_cibatadv_primary_if_get_selected(struct batadv_priv *bat_priv)
1308c2ecf20Sopenharmony_ci{
1318c2ecf20Sopenharmony_ci	struct batadv_hard_iface *hard_iface;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	rcu_read_lock();
1348c2ecf20Sopenharmony_ci	hard_iface = rcu_dereference(bat_priv->primary_if);
1358c2ecf20Sopenharmony_ci	if (!hard_iface)
1368c2ecf20Sopenharmony_ci		goto out;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	if (!kref_get_unless_zero(&hard_iface->refcount))
1398c2ecf20Sopenharmony_ci		hard_iface = NULL;
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ciout:
1428c2ecf20Sopenharmony_ci	rcu_read_unlock();
1438c2ecf20Sopenharmony_ci	return hard_iface;
1448c2ecf20Sopenharmony_ci}
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */
147