summaryrefslogtreecommitdiff
path: root/net/batman-adv/bat_iv_ogm.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/bat_iv_ogm.c')
-rw-r--r--net/batman-adv/bat_iv_ogm.c112
1 files changed, 60 insertions, 52 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 74b49c35ddc1..458879d21d66 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -23,6 +23,7 @@
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
+#include <linux/minmax.h>
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
@@ -36,6 +37,7 @@
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/string.h>
+#include <linux/string_choices.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include <net/genetlink.h>
@@ -128,7 +130,7 @@ static u8 batadv_ring_buffer_avg(const u8 lq_recv[])
/**
* batadv_iv_ogm_orig_get() - retrieve or create (if does not exist) an
* originator
- * @bat_priv: the bat priv with all the soft interface information
+ * @bat_priv: the bat priv with all the mesh interface information
* @addr: mac address of the originator
*
* Return: the originator object corresponding to the passed mac address or NULL
@@ -324,15 +326,14 @@ batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
/* check if there is enough space for the optional TVLV */
next_buff_pos += ntohs(ogm_packet->tvlv_len);
- return (next_buff_pos <= packet_len) &&
- (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
+ return next_buff_pos <= packet_len;
}
/* send a batman ogm to a given interface */
static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
struct batadv_hard_iface *hard_iface)
{
- struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
const char *fwd_str;
u8 packet_num;
s16 buff_pos;
@@ -354,7 +355,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
/* we might have aggregated direct link packets with an
* ordinary base packet
*/
- if (forw_packet->direct_link_flags & BIT(packet_num) &&
+ if (test_bit(packet_num, forw_packet->direct_link_flags) &&
forw_packet->if_incoming == hard_iface)
batadv_ogm_packet->flags |= BATADV_DIRECTLINK;
else
@@ -371,8 +372,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
batadv_ogm_packet->orig,
ntohl(batadv_ogm_packet->seqno),
batadv_ogm_packet->tq, batadv_ogm_packet->ttl,
- ((batadv_ogm_packet->flags & BATADV_DIRECTLINK) ?
- "on" : "off"),
+ str_on_off(batadv_ogm_packet->flags & BATADV_DIRECTLINK),
hard_iface->net_dev->name,
hard_iface->net_dev->dev_addr);
@@ -396,20 +396,20 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
/* send a batman ogm packet */
static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
{
- struct net_device *soft_iface;
+ struct net_device *mesh_iface;
if (!forw_packet->if_incoming) {
pr_err("Error - can't forward packet: incoming iface not specified\n");
return;
}
- soft_iface = forw_packet->if_incoming->soft_iface;
+ mesh_iface = forw_packet->if_incoming->mesh_iface;
if (WARN_ON(!forw_packet->if_outgoing))
return;
- if (forw_packet->if_outgoing->soft_iface != soft_iface) {
- pr_warn("%s: soft interface switch for queued OGM\n", __func__);
+ if (forw_packet->if_outgoing->mesh_iface != mesh_iface) {
+ pr_warn("%s: mesh interface switch for queued OGM\n", __func__);
return;
}
@@ -424,7 +424,7 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
* batadv_iv_ogm_can_aggregate() - find out if an OGM can be aggregated on an
* existing forward packet
* @new_bat_ogm_packet: OGM packet to be aggregated
- * @bat_priv: the bat priv with all the soft interface information
+ * @bat_priv: the bat priv with all the mesh interface information
* @packet_len: (total) length of the OGM
* @send_time: timestamp (jiffies) when the packet is to be sent
* @directlink: true if this is a direct link packet
@@ -444,28 +444,37 @@ batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
const struct batadv_forw_packet *forw_packet)
{
struct batadv_ogm_packet *batadv_ogm_packet;
- int aggregated_bytes = forw_packet->packet_len + packet_len;
+ unsigned int aggregated_bytes = forw_packet->packet_len + packet_len;
struct batadv_hard_iface *primary_if = NULL;
+ u8 packet_num = forw_packet->num_packets;
bool res = false;
unsigned long aggregation_end_time;
+ unsigned int max_bytes;
batadv_ogm_packet = (struct batadv_ogm_packet *)forw_packet->skb->data;
aggregation_end_time = send_time;
aggregation_end_time += msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
+ max_bytes = min_t(unsigned int, if_outgoing->net_dev->mtu,
+ BATADV_MAX_AGGREGATION_BYTES);
+
/* we can aggregate the current packet to this aggregated packet
* if:
*
* - the send time is within our MAX_AGGREGATION_MS time
* - the resulting packet won't be bigger than
- * MAX_AGGREGATION_BYTES
+ * MAX_AGGREGATION_BYTES and MTU of the outgoing interface
+ * - the number of packets is lower than MAX_AGGREGATION_PACKETS
* otherwise aggregation is not possible
*/
if (!time_before(send_time, forw_packet->send_time) ||
!time_after_eq(aggregation_end_time, forw_packet->send_time))
return false;
- if (aggregated_bytes > BATADV_MAX_AGGREGATION_BYTES)
+ if (aggregated_bytes > max_bytes)
+ return false;
+
+ if (packet_num >= BATADV_MAX_AGGREGATION_PACKETS)
return false;
/* packet is not leaving on the same interface. */
@@ -540,16 +549,16 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
struct batadv_hard_iface *if_outgoing,
int own_packet)
{
- struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
struct batadv_forw_packet *forw_packet_aggr;
struct sk_buff *skb;
unsigned char *skb_buff;
unsigned int skb_size;
atomic_t *queue_left = own_packet ? NULL : &bat_priv->batman_queue_left;
- if (atomic_read(&bat_priv->aggregated_ogms) &&
- packet_len < BATADV_MAX_AGGREGATION_BYTES)
- skb_size = BATADV_MAX_AGGREGATION_BYTES;
+ if (atomic_read(&bat_priv->aggregated_ogms))
+ skb_size = max_t(unsigned int, BATADV_MAX_AGGREGATION_BYTES,
+ packet_len);
else
skb_size = packet_len;
@@ -574,12 +583,13 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
memcpy(skb_buff, packet_buff, packet_len);
forw_packet_aggr->own = own_packet;
- forw_packet_aggr->direct_link_flags = BATADV_NO_FLAGS;
+ bitmap_zero(forw_packet_aggr->direct_link_flags,
+ BATADV_MAX_AGGREGATION_PACKETS);
forw_packet_aggr->send_time = send_time;
/* save packet direct link flag status */
if (direct_link)
- forw_packet_aggr->direct_link_flags |= 1;
+ set_bit(0, forw_packet_aggr->direct_link_flags);
INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work,
batadv_iv_send_outstanding_bat_ogm_packet);
@@ -592,22 +602,20 @@ static void batadv_iv_ogm_aggregate(struct batadv_forw_packet *forw_packet_aggr,
const unsigned char *packet_buff,
int packet_len, bool direct_link)
{
- unsigned long new_direct_link_flag;
-
skb_put_data(forw_packet_aggr->skb, packet_buff, packet_len);
forw_packet_aggr->packet_len += packet_len;
- forw_packet_aggr->num_packets++;
/* save packet direct link flag status */
- if (direct_link) {
- new_direct_link_flag = BIT(forw_packet_aggr->num_packets);
- forw_packet_aggr->direct_link_flags |= new_direct_link_flag;
- }
+ if (direct_link)
+ set_bit(forw_packet_aggr->num_packets,
+ forw_packet_aggr->direct_link_flags);
+
+ forw_packet_aggr->num_packets++;
}
/**
* batadv_iv_ogm_queue_add() - queue up an OGM for transmission
- * @bat_priv: the bat priv with all the soft interface information
+ * @bat_priv: the bat priv with all the mesh interface information
* @packet_buff: pointer to the OGM
* @packet_len: (total) length of the OGM
* @if_incoming: interface where the packet was received
@@ -686,7 +694,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
struct batadv_hard_iface *if_incoming,
struct batadv_hard_iface *if_outgoing)
{
- struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
u16 tvlv_len;
if (batadv_ogm_packet->ttl <= 1) {
@@ -739,7 +747,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
static void
batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
{
- struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
struct batadv_hashtable *hash = bat_priv->orig_hash;
struct hlist_head *head;
struct batadv_orig_node *orig_node;
@@ -778,7 +786,7 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
*/
static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
{
- struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
struct batadv_ogm_packet *batadv_ogm_packet;
struct batadv_hard_iface *primary_if, *tmp_hard_iface;
@@ -840,7 +848,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
*/
rcu_read_lock();
list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) {
- if (tmp_hard_iface->soft_iface != hard_iface->soft_iface)
+ if (tmp_hard_iface->mesh_iface != hard_iface->mesh_iface)
continue;
if (!kref_get_unless_zero(&tmp_hard_iface->refcount))
@@ -901,7 +909,7 @@ static u8 batadv_iv_orig_ifinfo_sum(struct batadv_orig_node *orig_node,
/**
* batadv_iv_ogm_orig_update() - use OGM to update corresponding data in an
* originator
- * @bat_priv: the bat priv with all the soft interface information
+ * @bat_priv: the bat priv with all the mesh interface information
* @orig_node: the orig node who originally emitted the ogm packet
* @orig_ifinfo: ifinfo for the outgoing interface of the orig_node
* @ethhdr: Ethernet header of the OGM
@@ -1065,7 +1073,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
struct batadv_hard_iface *if_incoming,
struct batadv_hard_iface *if_outgoing)
{
- struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node;
struct batadv_neigh_ifinfo *neigh_ifinfo;
u8 total_count;
@@ -1207,7 +1215,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr,
const struct batadv_hard_iface *if_incoming,
struct batadv_hard_iface *if_outgoing)
{
- struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
struct batadv_orig_node *orig_node;
struct batadv_orig_ifinfo *orig_ifinfo = NULL;
struct batadv_neigh_node *neigh_node;
@@ -1309,7 +1317,7 @@ batadv_iv_ogm_process_per_outif(const struct sk_buff *skb, int ogm_offset,
struct batadv_hard_iface *if_incoming,
struct batadv_hard_iface *if_outgoing)
{
- struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
struct batadv_hardif_neigh_node *hardif_neigh = NULL;
struct batadv_neigh_node *router = NULL;
struct batadv_neigh_node *router_router = NULL;
@@ -1549,7 +1557,7 @@ static void batadv_iv_ogm_process_reply(struct batadv_ogm_packet *ogm_packet,
static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
struct batadv_hard_iface *if_incoming)
{
- struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
struct batadv_orig_node *orig_neigh_node, *orig_node;
struct batadv_hard_iface *hard_iface;
struct batadv_ogm_packet *ogm_packet;
@@ -1599,7 +1607,7 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
if (hard_iface->if_status != BATADV_IF_ACTIVE)
continue;
- if (hard_iface->soft_iface != if_incoming->soft_iface)
+ if (hard_iface->mesh_iface != if_incoming->mesh_iface)
continue;
if (batadv_compare_eth(ethhdr->h_source,
@@ -1664,7 +1672,7 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
if (hard_iface->if_status != BATADV_IF_ACTIVE)
continue;
- if (hard_iface->soft_iface != bat_priv->soft_iface)
+ if (hard_iface->mesh_iface != bat_priv->mesh_iface)
continue;
if (!kref_get_unless_zero(&hard_iface->refcount))
@@ -1690,7 +1698,7 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
delayed_work = to_delayed_work(work);
forw_packet = container_of(delayed_work, struct batadv_forw_packet,
delayed_work);
- bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
+ bat_priv = netdev_priv(forw_packet->if_incoming->mesh_iface);
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
dropped = true;
@@ -1721,7 +1729,7 @@ out:
static int batadv_iv_ogm_receive(struct sk_buff *skb,
struct batadv_hard_iface *if_incoming)
{
- struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
+ struct batadv_priv *bat_priv = netdev_priv(if_incoming->mesh_iface);
struct batadv_ogm_packet *ogm_packet;
u8 *packet_pos;
int ogm_offset;
@@ -1800,7 +1808,7 @@ batadv_iv_ogm_neigh_get_tq_avg(struct batadv_neigh_node *neigh_node,
* @msg: Netlink message to dump into
* @portid: Port making netlink request
* @seq: Sequence number of netlink message
- * @bat_priv: The bat priv with all the soft interface information
+ * @bat_priv: The bat priv with all the mesh interface information
* @if_outgoing: Limit dump to entries with this outgoing interface
* @orig_node: Originator to dump
* @neigh_node: Single hops neighbour
@@ -1863,7 +1871,7 @@ batadv_iv_ogm_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
* @msg: Netlink message to dump into
* @portid: Port making netlink request
* @seq: Sequence number of netlink message
- * @bat_priv: The bat priv with all the soft interface information
+ * @bat_priv: The bat priv with all the mesh interface information
* @if_outgoing: Limit dump to entries with this outgoing interface
* @orig_node: Originator to dump
* @sub_s: Number of sub entries to skip
@@ -1925,7 +1933,7 @@ batadv_iv_ogm_orig_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
* @msg: Netlink message to dump into
* @portid: Port making netlink request
* @seq: Sequence number of netlink message
- * @bat_priv: The bat priv with all the soft interface information
+ * @bat_priv: The bat priv with all the mesh interface information
* @if_outgoing: Limit dump to entries with this outgoing interface
* @head: Bucket to be dumped
* @idx_s: Number of entries to be skipped
@@ -1966,7 +1974,7 @@ batadv_iv_ogm_orig_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
* batadv_iv_ogm_orig_dump() - Dump the originators into a message
* @msg: Netlink message to dump into
* @cb: Control block containing additional options
- * @bat_priv: The bat priv with all the soft interface information
+ * @bat_priv: The bat priv with all the mesh interface information
* @if_outgoing: Limit dump to entries with this outgoing interface
*/
static void
@@ -2088,7 +2096,7 @@ batadv_iv_ogm_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq,
* @msg: Netlink message to dump into
* @portid: Port making netlink request
* @seq: Sequence number of netlink message
- * @bat_priv: The bat priv with all the soft interface information
+ * @bat_priv: The bat priv with all the mesh interface information
* @hard_iface: Hard interface to dump the neighbours for
* @idx_s: Number of entries to skip
*
@@ -2125,7 +2133,7 @@ batadv_iv_ogm_neigh_dump_hardif(struct sk_buff *msg, u32 portid, u32 seq,
* batadv_iv_ogm_neigh_dump() - Dump the neighbours into a message
* @msg: Netlink message to dump into
* @cb: Control block containing additional options
- * @bat_priv: The bat priv with all the soft interface information
+ * @bat_priv: The bat priv with all the mesh interface information
* @single_hardif: Limit dump to this hard interface
*/
static void
@@ -2152,7 +2160,7 @@ batadv_iv_ogm_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
} else {
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list,
list) {
- if (hard_iface->soft_iface != bat_priv->soft_iface)
+ if (hard_iface->mesh_iface != bat_priv->mesh_iface)
continue;
if (i_hardif++ < i_hardif_s)
@@ -2236,7 +2244,7 @@ static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
/**
* batadv_iv_init_sel_class() - initialize GW selection class
- * @bat_priv: the bat priv with all the soft interface information
+ * @bat_priv: the bat priv with all the mesh interface information
*/
static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv)
{
@@ -2391,7 +2399,7 @@ out:
* @msg: Netlink message to dump into
* @portid: Port making netlink request
* @cb: Control block containing additional options
- * @bat_priv: The bat priv with all the soft interface information
+ * @bat_priv: The bat priv with all the mesh interface information
* @gw_node: Gateway to be dumped
*
* Return: Error code, or 0 on success
@@ -2466,7 +2474,7 @@ out:
* batadv_iv_gw_dump() - Dump gateways into a message
* @msg: Netlink message to dump into
* @cb: Control block containing additional options
- * @bat_priv: The bat priv with all the soft interface information
+ * @bat_priv: The bat priv with all the mesh interface information
*/
static void batadv_iv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb,
struct batadv_priv *bat_priv)