Commit d9b8b984 authored by David S. Miller's avatar David S. Miller

Merge tag 'batadv-next-for-davem-20200630' of git://git.open-mesh.org/linux-merge

Simon Wunderlich says:

====================
This feature/cleanup patchset includes the following patches:

 - bump version strings, by Simon Wunderlich

 - update mailing list URL, by Sven Eckelmann

 - fix typos and grammar in documentation, by Sven Eckelmann

 - introduce a configurable per interface hop penalty,
   by Linus Luessing
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 65951a9e 3bda14d0
...@@ -73,7 +73,7 @@ lower value. This will make the mesh more responsive to topology changes, but ...@@ -73,7 +73,7 @@ lower value. This will make the mesh more responsive to topology changes, but
will also increase the overhead. will also increase the overhead.
Information about the current state can be accessed via the batadv generic Information about the current state can be accessed via the batadv generic
netlink family. batctl provides human readable version via its debug tables netlink family. batctl provides a human readable version via its debug tables
subcommands. subcommands.
...@@ -115,8 +115,8 @@ are prefixed with "batman-adv:" So to see just these messages try:: ...@@ -115,8 +115,8 @@ are prefixed with "batman-adv:" So to see just these messages try::
$ dmesg | grep batman-adv $ dmesg | grep batman-adv
When investigating problems with your mesh network, it is sometimes necessary to When investigating problems with your mesh network, it is sometimes necessary to
see more detail debug messages. This must be enabled when compiling the see more detailed debug messages. This must be enabled when compiling the
batman-adv module. When building batman-adv as part of kernel, use "make batman-adv module. When building batman-adv as part of the kernel, use "make
menuconfig" and enable the option ``B.A.T.M.A.N. debugging`` menuconfig" and enable the option ``B.A.T.M.A.N. debugging``
(``CONFIG_BATMAN_ADV_DEBUG=y``). (``CONFIG_BATMAN_ADV_DEBUG=y``).
...@@ -160,7 +160,7 @@ IRC: ...@@ -160,7 +160,7 @@ IRC:
#batman on irc.freenode.org #batman on irc.freenode.org
Mailing-list: Mailing-list:
b.a.t.m.a.n@open-mesh.org (optional subscription at b.a.t.m.a.n@open-mesh.org (optional subscription at
https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) https://lists.open-mesh.org/mailman3/postorius/lists/b.a.t.m.a.n.lists.open-mesh.org/)
You can also contact the Authors: You can also contact the Authors:
......
...@@ -72,8 +72,8 @@ enum batadv_subtype { ...@@ -72,8 +72,8 @@ enum batadv_subtype {
/** /**
* enum batadv_iv_flags - flags used in B.A.T.M.A.N. IV OGM packets * enum batadv_iv_flags - flags used in B.A.T.M.A.N. IV OGM packets
* @BATADV_NOT_BEST_NEXT_HOP: flag is set when ogm packet is forwarded and was * @BATADV_NOT_BEST_NEXT_HOP: flag is set when the ogm packet is forwarded and
* previously received from someone else than the best neighbor. * was previously received from someone other than the best neighbor.
* @BATADV_PRIMARIES_FIRST_HOP: flag unused. * @BATADV_PRIMARIES_FIRST_HOP: flag unused.
* @BATADV_DIRECTLINK: flag is for the first hop or if rebroadcasted from a * @BATADV_DIRECTLINK: flag is for the first hop or if rebroadcasted from a
* one hop neighbor on the interface where it was originally received. * one hop neighbor on the interface where it was originally received.
...@@ -195,8 +195,8 @@ struct batadv_bla_claim_dst { ...@@ -195,8 +195,8 @@ struct batadv_bla_claim_dst {
/** /**
* struct batadv_ogm_packet - ogm (routing protocol) packet * struct batadv_ogm_packet - ogm (routing protocol) packet
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @flags: contains routing relevant flags - see enum batadv_iv_flags * @flags: contains routing relevant flags - see enum batadv_iv_flags
* @seqno: sequence identification * @seqno: sequence identification
* @orig: address of the source node * @orig: address of the source node
...@@ -247,7 +247,7 @@ struct batadv_ogm2_packet { ...@@ -247,7 +247,7 @@ struct batadv_ogm2_packet {
/** /**
* struct batadv_elp_packet - elp (neighbor discovery) packet * struct batadv_elp_packet - elp (neighbor discovery) packet
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @orig: originator mac address * @orig: originator mac address
* @seqno: sequence number * @seqno: sequence number
* @elp_interval: currently used ELP sending interval in ms * @elp_interval: currently used ELP sending interval in ms
...@@ -265,15 +265,15 @@ struct batadv_elp_packet { ...@@ -265,15 +265,15 @@ struct batadv_elp_packet {
/** /**
* struct batadv_icmp_header - common members among all the ICMP packets * struct batadv_icmp_header - common members among all the ICMP packets
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @msg_type: ICMP packet type * @msg_type: ICMP packet type
* @dst: address of the destination node * @dst: address of the destination node
* @orig: address of the source node * @orig: address of the source node
* @uid: local ICMP socket identifier * @uid: local ICMP socket identifier
* @align: not used - useful for alignment purposes only * @align: not used - useful for alignment purposes only
* *
* This structure is used for ICMP packets parsing only and it is never sent * This structure is used for ICMP packet parsing only and it is never sent
* over the wire. The alignment field at the end is there to ensure that * over the wire. The alignment field at the end is there to ensure that
* members are padded the same way as they are in real packets. * members are padded the same way as they are in real packets.
*/ */
...@@ -291,8 +291,8 @@ struct batadv_icmp_header { ...@@ -291,8 +291,8 @@ struct batadv_icmp_header {
/** /**
* struct batadv_icmp_packet - ICMP packet * struct batadv_icmp_packet - ICMP packet
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @msg_type: ICMP packet type * @msg_type: ICMP packet type
* @dst: address of the destination node * @dst: address of the destination node
* @orig: address of the source node * @orig: address of the source node
...@@ -315,8 +315,8 @@ struct batadv_icmp_packet { ...@@ -315,8 +315,8 @@ struct batadv_icmp_packet {
/** /**
* struct batadv_icmp_tp_packet - ICMP TP Meter packet * struct batadv_icmp_tp_packet - ICMP TP Meter packet
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @msg_type: ICMP packet type * @msg_type: ICMP packet type
* @dst: address of the destination node * @dst: address of the destination node
* @orig: address of the source node * @orig: address of the source node
...@@ -358,8 +358,8 @@ enum batadv_icmp_tp_subtype { ...@@ -358,8 +358,8 @@ enum batadv_icmp_tp_subtype {
/** /**
* struct batadv_icmp_packet_rr - ICMP RouteRecord packet * struct batadv_icmp_packet_rr - ICMP RouteRecord packet
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @msg_type: ICMP packet type * @msg_type: ICMP packet type
* @dst: address of the destination node * @dst: address of the destination node
* @orig: address of the source node * @orig: address of the source node
...@@ -397,8 +397,8 @@ struct batadv_icmp_packet_rr { ...@@ -397,8 +397,8 @@ struct batadv_icmp_packet_rr {
/** /**
* struct batadv_unicast_packet - unicast packet for network payload * struct batadv_unicast_packet - unicast packet for network payload
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @ttvn: translation table version number * @ttvn: translation table version number
* @dest: originator destination of the unicast packet * @dest: originator destination of the unicast packet
*/ */
...@@ -433,8 +433,8 @@ struct batadv_unicast_4addr_packet { ...@@ -433,8 +433,8 @@ struct batadv_unicast_4addr_packet {
/** /**
* struct batadv_frag_packet - fragmented packet * struct batadv_frag_packet - fragmented packet
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @dest: final destination used when routing fragments * @dest: final destination used when routing fragments
* @orig: originator of the fragment used when merging the packet * @orig: originator of the fragment used when merging the packet
* @no: fragment number within this sequence * @no: fragment number within this sequence
...@@ -467,8 +467,8 @@ struct batadv_frag_packet { ...@@ -467,8 +467,8 @@ struct batadv_frag_packet {
/** /**
* struct batadv_bcast_packet - broadcast packet for network payload * struct batadv_bcast_packet - broadcast packet for network payload
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @reserved: reserved byte for alignment * @reserved: reserved byte for alignment
* @seqno: sequence identification * @seqno: sequence identification
* @orig: originator of the broadcast packet * @orig: originator of the broadcast packet
...@@ -488,10 +488,10 @@ struct batadv_bcast_packet { ...@@ -488,10 +488,10 @@ struct batadv_bcast_packet {
/** /**
* struct batadv_coded_packet - network coded packet * struct batadv_coded_packet - network coded packet
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @first_source: original source of first included packet * @first_source: original source of first included packet
* @first_orig_dest: original destinal of first included packet * @first_orig_dest: original destination of first included packet
* @first_crc: checksum of first included packet * @first_crc: checksum of first included packet
* @first_ttvn: tt-version number of first included packet * @first_ttvn: tt-version number of first included packet
* @second_ttl: ttl of second packet * @second_ttl: ttl of second packet
...@@ -523,8 +523,8 @@ struct batadv_coded_packet { ...@@ -523,8 +523,8 @@ struct batadv_coded_packet {
/** /**
* struct batadv_unicast_tvlv_packet - generic unicast packet with tvlv payload * struct batadv_unicast_tvlv_packet - generic unicast packet with tvlv payload
* @packet_type: batman-adv packet type, part of the general header * @packet_type: batman-adv packet type, part of the general header
* @version: batman-adv protocol version, part of the genereal header * @version: batman-adv protocol version, part of the general header
* @ttl: time to live for this packet, part of the genereal header * @ttl: time to live for this packet, part of the general header
* @reserved: reserved field (for packet alignment) * @reserved: reserved field (for packet alignment)
* @src: address of the source * @src: address of the source
* @dst: address of the destination * @dst: address of the destination
......
...@@ -69,7 +69,7 @@ enum batadv_tt_client_flags { ...@@ -69,7 +69,7 @@ enum batadv_tt_client_flags {
/** /**
* @BATADV_TT_CLIENT_TEMP: this global client has been detected to be * @BATADV_TT_CLIENT_TEMP: this global client has been detected to be
* part of the network but no nnode has already announced it * part of the network but no node has already announced it
*/ */
BATADV_TT_CLIENT_TEMP = (1 << 11), BATADV_TT_CLIENT_TEMP = (1 << 11),
}; };
...@@ -131,7 +131,7 @@ enum batadv_gw_modes { ...@@ -131,7 +131,7 @@ enum batadv_gw_modes {
/** @BATADV_GW_MODE_CLIENT: send DHCP requests to gw servers */ /** @BATADV_GW_MODE_CLIENT: send DHCP requests to gw servers */
BATADV_GW_MODE_CLIENT, BATADV_GW_MODE_CLIENT,
/** @BATADV_GW_MODE_SERVER: announce itself as gatway server */ /** @BATADV_GW_MODE_SERVER: announce itself as gateway server */
BATADV_GW_MODE_SERVER, BATADV_GW_MODE_SERVER,
}; };
...@@ -427,7 +427,8 @@ enum batadv_nl_attrs { ...@@ -427,7 +427,8 @@ enum batadv_nl_attrs {
/** /**
* @BATADV_ATTR_HOP_PENALTY: defines the penalty which will be applied * @BATADV_ATTR_HOP_PENALTY: defines the penalty which will be applied
* to an originator message's tq-field on every hop. * to an originator message's tq-field on every hop and/or per
* hard interface
*/ */
BATADV_ATTR_HOP_PENALTY, BATADV_ATTR_HOP_PENALTY,
......
...@@ -134,7 +134,7 @@ static u8 batadv_ring_buffer_avg(const u8 lq_recv[]) ...@@ -134,7 +134,7 @@ static u8 batadv_ring_buffer_avg(const u8 lq_recv[])
* *
* Return: the originator object corresponding to the passed mac address or NULL * Return: the originator object corresponding to the passed mac address or NULL
* on failure. * on failure.
* If the object does not exists it is created an initialised. * If the object does not exist, it is created and initialised.
*/ */
static struct batadv_orig_node * static struct batadv_orig_node *
batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr) batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
...@@ -871,7 +871,7 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) ...@@ -871,7 +871,7 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
} }
/** /**
* batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over iterface * batadv_iv_orig_ifinfo_sum() - Get bcast_own sum for originator over interface
* @orig_node: originator which reproadcasted the OGMs directly * @orig_node: originator which reproadcasted the OGMs directly
* @if_outgoing: interface which transmitted the original OGM and received the * @if_outgoing: interface which transmitted the original OGM and received the
* direct rebroadcast * direct rebroadcast
...@@ -1075,10 +1075,10 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, ...@@ -1075,10 +1075,10 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
struct batadv_neigh_ifinfo *neigh_ifinfo; struct batadv_neigh_ifinfo *neigh_ifinfo;
u8 total_count; u8 total_count;
u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
unsigned int tq_iface_hop_penalty = BATADV_TQ_MAX_VALUE;
unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
unsigned int tq_asym_penalty, inv_asym_penalty; unsigned int tq_asym_penalty, inv_asym_penalty;
unsigned int combined_tq; unsigned int combined_tq;
unsigned int tq_iface_penalty;
bool ret = false; bool ret = false;
/* find corresponding one hop neighbor */ /* find corresponding one hop neighbor */
...@@ -1157,31 +1157,32 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, ...@@ -1157,31 +1157,32 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube; inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube;
inv_asym_penalty /= neigh_rq_max_cube; inv_asym_penalty /= neigh_rq_max_cube;
tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty; tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty;
tq_iface_hop_penalty -= atomic_read(&if_incoming->hop_penalty);
/* penalize if the OGM is forwarded on the same interface. WiFi /* penalize if the OGM is forwarded on the same interface. WiFi
* interfaces and other half duplex devices suffer from throughput * interfaces and other half duplex devices suffer from throughput
* drops as they can't send and receive at the same time. * drops as they can't send and receive at the same time.
*/ */
tq_iface_penalty = BATADV_TQ_MAX_VALUE;
if (if_outgoing && if_incoming == if_outgoing && if (if_outgoing && if_incoming == if_outgoing &&
batadv_is_wifi_hardif(if_outgoing)) batadv_is_wifi_hardif(if_outgoing))
tq_iface_penalty = batadv_hop_penalty(BATADV_TQ_MAX_VALUE, tq_iface_hop_penalty = batadv_hop_penalty(tq_iface_hop_penalty,
bat_priv); bat_priv);
combined_tq = batadv_ogm_packet->tq * combined_tq = batadv_ogm_packet->tq *
tq_own * tq_own *
tq_asym_penalty * tq_asym_penalty *
tq_iface_penalty; tq_iface_hop_penalty;
combined_tq /= BATADV_TQ_MAX_VALUE * combined_tq /= BATADV_TQ_MAX_VALUE *
BATADV_TQ_MAX_VALUE * BATADV_TQ_MAX_VALUE *
BATADV_TQ_MAX_VALUE; BATADV_TQ_MAX_VALUE;
batadv_ogm_packet->tq = combined_tq; batadv_ogm_packet->tq = combined_tq;
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"bidirectional: orig = %pM neigh = %pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n", "bidirectional: orig = %pM neigh = %pM => own_bcast = %2i, real recv = %2i, local tq: %3i, asym_penalty: %3i, iface_hop_penalty: %3i, total tq: %3i, if_incoming = %s, if_outgoing = %s\n",
orig_node->orig, orig_neigh_node->orig, total_count, orig_node->orig, orig_neigh_node->orig, total_count,
neigh_rq_count, tq_own, tq_asym_penalty, tq_iface_penalty, neigh_rq_count, tq_own, tq_asym_penalty,
batadv_ogm_packet->tq, if_incoming->net_dev->name, tq_iface_hop_penalty, batadv_ogm_packet->tq,
if_incoming->net_dev->name,
if_outgoing ? if_outgoing->net_dev->name : "DEFAULT"); if_outgoing ? if_outgoing->net_dev->name : "DEFAULT");
/* if link has the minimum required transmission quality /* if link has the minimum required transmission quality
...@@ -1554,7 +1555,7 @@ static void batadv_iv_ogm_process_reply(struct batadv_ogm_packet *ogm_packet, ...@@ -1554,7 +1555,7 @@ static void batadv_iv_ogm_process_reply(struct batadv_ogm_packet *ogm_packet,
* batadv_iv_ogm_process() - process an incoming batman iv OGM * batadv_iv_ogm_process() - process an incoming batman iv OGM
* @skb: the skb containing the OGM * @skb: the skb containing the OGM
* @ogm_offset: offset to the OGM which should be processed (for aggregates) * @ogm_offset: offset to the OGM which should be processed (for aggregates)
* @if_incoming: the interface where this packet was receved * @if_incoming: the interface where this packet was received
*/ */
static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset, static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
struct batadv_hard_iface *if_incoming) struct batadv_hard_iface *if_incoming)
...@@ -2288,7 +2289,7 @@ batadv_iv_ogm_neigh_dump_hardif(struct sk_buff *msg, u32 portid, u32 seq, ...@@ -2288,7 +2289,7 @@ batadv_iv_ogm_neigh_dump_hardif(struct sk_buff *msg, u32 portid, u32 seq,
* @msg: Netlink message to dump into * @msg: Netlink message to dump into
* @cb: Control block containing additional options * @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 soft interface information
* @single_hardif: Limit dump to this hard interfaace * @single_hardif: Limit dump to this hard interface
*/ */
static void static void
batadv_iv_ogm_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb, batadv_iv_ogm_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
......
...@@ -60,7 +60,7 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface) ...@@ -60,7 +60,7 @@ static void batadv_v_elp_start_timer(struct batadv_hard_iface *hard_iface)
* @neigh: the neighbour for which the throughput has to be obtained * @neigh: the neighbour for which the throughput has to be obtained
* *
* Return: The throughput towards the given neighbour in multiples of 100kpbs * Return: The throughput towards the given neighbour in multiples of 100kpbs
* (a value of '1' equals to 0.1Mbps, '10' equals 1Mbps, etc). * (a value of '1' equals 0.1Mbps, '10' equals 1Mbps, etc).
*/ */
static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh)
{ {
...@@ -183,8 +183,8 @@ void batadv_v_elp_throughput_metric_update(struct work_struct *work) ...@@ -183,8 +183,8 @@ void batadv_v_elp_throughput_metric_update(struct work_struct *work)
* *
* Sends a predefined number of unicast wifi packets to a given neighbour in * Sends a predefined number of unicast wifi packets to a given neighbour in
* order to trigger the throughput estimation on this link by the RC algorithm. * order to trigger the throughput estimation on this link by the RC algorithm.
* Packets are sent only if there there is not enough payload unicast traffic * Packets are sent only if there is not enough payload unicast traffic towards
* towards this neighbour.. * this neighbour..
* *
* Return: True on success and false in case of error during skb preparation. * Return: True on success and false in case of error during skb preparation.
*/ */
...@@ -244,7 +244,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh) ...@@ -244,7 +244,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh)
* batadv_v_elp_periodic_work() - ELP periodic task per interface * batadv_v_elp_periodic_work() - ELP periodic task per interface
* @work: work queue item * @work: work queue item
* *
* Emits broadcast ELP message in regular intervals. * Emits broadcast ELP messages in regular intervals.
*/ */
static void batadv_v_elp_periodic_work(struct work_struct *work) static void batadv_v_elp_periodic_work(struct work_struct *work)
{ {
...@@ -499,7 +499,7 @@ static void batadv_v_elp_neigh_update(struct batadv_priv *bat_priv, ...@@ -499,7 +499,7 @@ static void batadv_v_elp_neigh_update(struct batadv_priv *bat_priv,
* @skb: the received packet * @skb: the received packet
* @if_incoming: the interface this packet was received through * @if_incoming: the interface this packet was received through
* *
* Return: NET_RX_SUCCESS and consumes the skb if the packet was peoperly * Return: NET_RX_SUCCESS and consumes the skb if the packet was properly
* processed or NET_RX_DROP in case of failure. * processed or NET_RX_DROP in case of failure.
*/ */
int batadv_v_elp_packet_recv(struct sk_buff *skb, int batadv_v_elp_packet_recv(struct sk_buff *skb,
......
...@@ -47,9 +47,9 @@ ...@@ -47,9 +47,9 @@
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @addr: the address of the originator * @addr: the address of the originator
* *
* Return: the orig_node corresponding to the specified address. If such object * Return: the orig_node corresponding to the specified address. If such an
* does not exist it is allocated here. In case of allocation failure returns * object does not exist, it is allocated here. In case of allocation failure
* NULL. * returns NULL.
*/ */
struct batadv_orig_node *batadv_v_ogm_orig_get(struct batadv_priv *bat_priv, struct batadv_orig_node *batadv_v_ogm_orig_get(struct batadv_priv *bat_priv,
const u8 *addr) const u8 *addr)
...@@ -172,7 +172,7 @@ static bool batadv_v_ogm_queue_left(struct sk_buff *skb, ...@@ -172,7 +172,7 @@ static bool batadv_v_ogm_queue_left(struct sk_buff *skb,
* batadv_v_ogm_aggr_list_free - free all elements in an aggregation queue * batadv_v_ogm_aggr_list_free - free all elements in an aggregation queue
* @hard_iface: the interface holding the aggregation queue * @hard_iface: the interface holding the aggregation queue
* *
* Empties the OGMv2 aggregation queue and frees all the skbs it contained. * Empties the OGMv2 aggregation queue and frees all the skbs it contains.
* *
* Caller needs to hold the hard_iface->bat_v.aggr_list.lock. * Caller needs to hold the hard_iface->bat_v.aggr_list.lock.
*/ */
...@@ -378,7 +378,7 @@ static void batadv_v_ogm_send(struct work_struct *work) ...@@ -378,7 +378,7 @@ static void batadv_v_ogm_send(struct work_struct *work)
* batadv_v_ogm_aggr_work() - OGM queue periodic task per interface * batadv_v_ogm_aggr_work() - OGM queue periodic task per interface
* @work: work queue item * @work: work queue item
* *
* Emits aggregated OGM message in regular intervals. * Emits aggregated OGM messages in regular intervals.
*/ */
void batadv_v_ogm_aggr_work(struct work_struct *work) void batadv_v_ogm_aggr_work(struct work_struct *work)
{ {
...@@ -399,7 +399,7 @@ void batadv_v_ogm_aggr_work(struct work_struct *work) ...@@ -399,7 +399,7 @@ void batadv_v_ogm_aggr_work(struct work_struct *work)
* batadv_v_ogm_iface_enable() - prepare an interface for B.A.T.M.A.N. V * batadv_v_ogm_iface_enable() - prepare an interface for B.A.T.M.A.N. V
* @hard_iface: the interface to prepare * @hard_iface: the interface to prepare
* *
* Takes care of scheduling own OGM sending routine for this interface. * Takes care of scheduling its own OGM sending routine for this interface.
* *
* Return: 0 on success or a negative error code otherwise * Return: 0 on success or a negative error code otherwise
*/ */
...@@ -455,15 +455,17 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface) ...@@ -455,15 +455,17 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
* @throughput: the current throughput * @throughput: the current throughput
* *
* Apply a penalty on the current throughput metric value based on the * Apply a penalty on the current throughput metric value based on the
* characteristic of the interface where the OGM has been received. The return * characteristic of the interface where the OGM has been received.
* value is computed as follows: *
* Initially the per hardif hop penalty is applied to the throughput. After
* that the return value is then computed as follows:
* - throughput * 50% if the incoming and outgoing interface are the * - throughput * 50% if the incoming and outgoing interface are the
* same WiFi interface and the throughput is above * same WiFi interface and the throughput is above
* 1MBit/s * 1MBit/s
* - throughput if the outgoing interface is the default * - throughput if the outgoing interface is the default
* interface (i.e. this OGM is processed for the * interface (i.e. this OGM is processed for the
* internal table and not forwarded) * internal table and not forwarded)
* - throughput * hop penalty otherwise * - throughput * node hop penalty otherwise
* *
* Return: the penalised throughput metric. * Return: the penalised throughput metric.
*/ */
...@@ -472,9 +474,14 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv, ...@@ -472,9 +474,14 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv,
struct batadv_hard_iface *if_outgoing, struct batadv_hard_iface *if_outgoing,
u32 throughput) u32 throughput)
{ {
int if_hop_penalty = atomic_read(&if_incoming->hop_penalty);
int hop_penalty = atomic_read(&bat_priv->hop_penalty); int hop_penalty = atomic_read(&bat_priv->hop_penalty);
int hop_penalty_max = BATADV_TQ_MAX_VALUE; int hop_penalty_max = BATADV_TQ_MAX_VALUE;
/* Apply per hardif hop penalty */
throughput = throughput * (hop_penalty_max - if_hop_penalty) /
hop_penalty_max;
/* Don't apply hop penalty in default originator table. */ /* Don't apply hop penalty in default originator table. */
if (if_outgoing == BATADV_IF_DEFAULT) if (if_outgoing == BATADV_IF_DEFAULT)
return throughput; return throughput;
...@@ -847,7 +854,7 @@ batadv_v_ogm_aggr_packet(int buff_pos, int packet_len, ...@@ -847,7 +854,7 @@ batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
* batadv_v_ogm_process() - process an incoming batman v OGM * batadv_v_ogm_process() - process an incoming batman v OGM
* @skb: the skb containing the OGM * @skb: the skb containing the OGM
* @ogm_offset: offset to the OGM which should be processed (for aggregates) * @ogm_offset: offset to the OGM which should be processed (for aggregates)
* @if_incoming: the interface where this packet was receved * @if_incoming: the interface where this packet was received
*/ */
static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset, static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
struct batadv_hard_iface *if_incoming) struct batadv_hard_iface *if_incoming)
......
...@@ -992,7 +992,7 @@ static bool batadv_handle_claim(struct batadv_priv *bat_priv, ...@@ -992,7 +992,7 @@ static bool batadv_handle_claim(struct batadv_priv *bat_priv,
* @hw_dst: the Hardware destination in the ARP Header * @hw_dst: the Hardware destination in the ARP Header
* @ethhdr: pointer to the Ethernet header of the claim frame * @ethhdr: pointer to the Ethernet header of the claim frame
* *
* checks if it is a claim packet and if its on the same group. * checks if it is a claim packet and if it's on the same group.
* This function also applies the group ID of the sender * This function also applies the group ID of the sender
* if it is in the same mesh. * if it is in the same mesh.
* *
...@@ -1757,7 +1757,7 @@ void batadv_bla_free(struct batadv_priv *bat_priv) ...@@ -1757,7 +1757,7 @@ void batadv_bla_free(struct batadv_priv *bat_priv)
* @vid: the VLAN ID of the frame * @vid: the VLAN ID of the frame
* *
* Checks if this packet is a loop detect frame which has been sent by us, * Checks if this packet is a loop detect frame which has been sent by us,
* throw an uevent and log the event if that is the case. * throws an uevent and logs the event if that is the case.
* *
* Return: true if it is a loop detect frame which is to be dropped, false * Return: true if it is a loop detect frame which is to be dropped, false
* otherwise. * otherwise.
...@@ -1815,7 +1815,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1815,7 +1815,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
* * we have to race for a claim * * we have to race for a claim
* * if the frame is allowed on the LAN * * if the frame is allowed on the LAN
* *
* in these cases, the skb is further handled by this function * In these cases, the skb is further handled by this function
* *
* Return: true if handled, otherwise it returns false and the caller shall * Return: true if handled, otherwise it returns false and the caller shall
* further process the skb. * further process the skb.
......
...@@ -666,7 +666,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst, ...@@ -666,7 +666,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst,
* @vid: VLAN identifier * @vid: VLAN identifier
* @packet_subtype: unicast4addr packet subtype to use * @packet_subtype: unicast4addr packet subtype to use
* *
* This function copies the skb with pskb_copy() and is sent as unicast packet * This function copies the skb with pskb_copy() and is sent as a unicast packet
* to each of the selected candidates. * to each of the selected candidates.
* *
* Return: true if the packet is sent to at least one candidate, false * Return: true if the packet is sent to at least one candidate, false
......
...@@ -102,8 +102,8 @@ static int batadv_frag_size_limit(void) ...@@ -102,8 +102,8 @@ static int batadv_frag_size_limit(void)
* *
* Caller must hold chain->lock. * Caller must hold chain->lock.
* *
* Return: true if chain is empty and caller can just insert the new fragment * Return: true if chain is empty and the caller can just insert the new
* without searching for the right position. * fragment without searching for the right position.
*/ */
static bool batadv_frag_init_chain(struct batadv_frag_table_entry *chain, static bool batadv_frag_init_chain(struct batadv_frag_table_entry *chain,
u16 seqno) u16 seqno)
...@@ -306,7 +306,7 @@ batadv_frag_merge_packets(struct hlist_head *chain) ...@@ -306,7 +306,7 @@ batadv_frag_merge_packets(struct hlist_head *chain)
* set *skb to merged packet; 2) Packet is buffered: Return true and set *skb * set *skb to merged packet; 2) Packet is buffered: Return true and set *skb
* to NULL; 3) Error: Return false and free skb. * to NULL; 3) Error: Return false and free skb.
* *
* Return: true when packet is merged or buffered, false when skb is not not * Return: true when the packet is merged or buffered, false when skb is not not
* used. * used.
*/ */
bool batadv_frag_skb_buffer(struct sk_buff **skb, bool batadv_frag_skb_buffer(struct sk_buff **skb,
......
...@@ -138,10 +138,10 @@ static bool batadv_mutual_parents(const struct net_device *dev1, ...@@ -138,10 +138,10 @@ static bool batadv_mutual_parents(const struct net_device *dev1,
* @net_dev: the device to check * @net_dev: the device to check
* *
* If the user creates any virtual device on top of a batman-adv interface, it * If the user creates any virtual device on top of a batman-adv interface, it
* is important to prevent this new interface to be used to create a new mesh * is important to prevent this new interface from being used to create a new
* network (this behaviour would lead to a batman-over-batman configuration). * mesh network (this behaviour would lead to a batman-over-batman
* This function recursively checks all the fathers of the device passed as * configuration). This function recursively checks all the fathers of the
* argument looking for a batman-adv soft interface. * device passed as argument looking for a batman-adv soft interface.
* *
* Return: true if the device is descendant of a batman-adv mesh interface (or * Return: true if the device is descendant of a batman-adv mesh interface (or
* if it is a batman-adv interface itself), false otherwise * if it is a batman-adv interface itself), false otherwise
...@@ -680,8 +680,8 @@ batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface) ...@@ -680,8 +680,8 @@ batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface)
* @slave: the interface enslaved in another master * @slave: the interface enslaved in another master
* @master: the master from which slave has to be removed * @master: the master from which slave has to be removed
* *
* Invoke ndo_del_slave on master passing slave as argument. In this way slave * Invoke ndo_del_slave on master passing slave as argument. In this way the
* is free'd and master can correctly change its internal state. * slave is free'd and the master can correctly change its internal state.
* *
* Return: 0 on success, a negative value representing the error otherwise * Return: 0 on success, a negative value representing the error otherwise
*/ */
...@@ -818,7 +818,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface, ...@@ -818,7 +818,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
* @soft_iface: soft interface to check * @soft_iface: soft interface to check
* *
* This function is only using RCU for locking - the result can therefore be * This function is only using RCU for locking - the result can therefore be
* off when another functions is modifying the list at the same time. The * off when another function is modifying the list at the same time. The
* caller can use the rtnl_lock to make sure that the count is accurate. * caller can use the rtnl_lock to make sure that the count is accurate.
* *
* Return: number of connected/enslaved hard interfaces * Return: number of connected/enslaved hard interfaces
...@@ -939,6 +939,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) ...@@ -939,6 +939,8 @@ batadv_hardif_add_interface(struct net_device *net_dev)
if (batadv_is_wifi_hardif(hard_iface)) if (batadv_is_wifi_hardif(hard_iface))
hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS; hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
atomic_set(&hard_iface->hop_penalty, 0);
batadv_v_hardif_init(hard_iface); batadv_v_hardif_init(hard_iface);
batadv_check_known_mac_addr(hard_iface->net_dev); batadv_check_known_mac_addr(hard_iface->net_dev);
......
...@@ -69,7 +69,7 @@ int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...) ...@@ -69,7 +69,7 @@ int batadv_debug_log(struct batadv_priv *bat_priv, const char *fmt, ...)
__printf(2, 3); __printf(2, 3);
/** /**
* _batadv_dbg() - Store debug output with(out) ratelimiting * _batadv_dbg() - Store debug output with(out) rate limiting
* @type: type of debug message * @type: type of debug message
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @ratelimited: whether output should be rate limited * @ratelimited: whether output should be rate limited
...@@ -95,7 +95,7 @@ static inline void _batadv_dbg(int type __always_unused, ...@@ -95,7 +95,7 @@ static inline void _batadv_dbg(int type __always_unused,
#endif #endif
/** /**
* batadv_dbg() - Store debug output without ratelimiting * batadv_dbg() - Store debug output without rate limiting
* @type: type of debug message * @type: type of debug message
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @arg: format string and variable arguments * @arg: format string and variable arguments
...@@ -104,7 +104,7 @@ static inline void _batadv_dbg(int type __always_unused, ...@@ -104,7 +104,7 @@ static inline void _batadv_dbg(int type __always_unused,
_batadv_dbg(type, bat_priv, 0, ## arg) _batadv_dbg(type, bat_priv, 0, ## arg)
/** /**
* batadv_dbg_ratelimited() - Store debug output with ratelimiting * batadv_dbg_ratelimited() - Store debug output with rate limiting
* @type: type of debug message * @type: type of debug message
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @arg: format string and variable arguments * @arg: format string and variable arguments
......
...@@ -666,7 +666,7 @@ unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len) ...@@ -666,7 +666,7 @@ unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len)
* @vid: the VLAN identifier for which the AP isolation attributed as to be * @vid: the VLAN identifier for which the AP isolation attributed as to be
* looked up * looked up
* *
* Return: true if AP isolation is on for the VLAN idenfied by vid, false * Return: true if AP isolation is on for the VLAN identified by vid, false
* otherwise * otherwise
*/ */
bool batadv_vlan_ap_isola_get(struct batadv_priv *bat_priv, unsigned short vid) bool batadv_vlan_ap_isola_get(struct batadv_priv *bat_priv, unsigned short vid)
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv" #define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION #ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2020.2" #define BATADV_SOURCE_VERSION "2020.3"
#endif #endif
/* B.A.T.M.A.N. parameters */ /* B.A.T.M.A.N. parameters */
...@@ -308,7 +308,7 @@ static inline bool batadv_has_timed_out(unsigned long timestamp, ...@@ -308,7 +308,7 @@ static inline bool batadv_has_timed_out(unsigned long timestamp,
* @y: value to compare @x against * @y: value to compare @x against
* *
* It handles overflows/underflows and can correctly check for a predecessor * It handles overflows/underflows and can correctly check for a predecessor
* unless the variable sequence number has grown by more then * unless the variable sequence number has grown by more than
* 2**(bitwidth(x)-1)-1. * 2**(bitwidth(x)-1)-1.
* *
* This means that for a u8 with the maximum value 255, it would think: * This means that for a u8 with the maximum value 255, it would think:
...@@ -330,11 +330,11 @@ static inline bool batadv_has_timed_out(unsigned long timestamp, ...@@ -330,11 +330,11 @@ static inline bool batadv_has_timed_out(unsigned long timestamp,
/** /**
* batadv_seq_after() - Checks if a sequence number x is a successor of y * batadv_seq_after() - Checks if a sequence number x is a successor of y
* @x: potential sucessor of @y * @x: potential successor of @y
* @y: value to compare @x against * @y: value to compare @x against
* *
* It handles overflows/underflows and can correctly check for a successor * It handles overflows/underflows and can correctly check for a successor
* unless the variable sequence number has grown by more then * unless the variable sequence number has grown by more than
* 2**(bitwidth(x)-1)-1. * 2**(bitwidth(x)-1)-1.
* *
* This means that for a u8 with the maximum value 255, it would think: * This means that for a u8 with the maximum value 255, it would think:
......
...@@ -510,7 +510,7 @@ batadv_mcast_mla_softif_get_ipv6(struct net_device *dev, ...@@ -510,7 +510,7 @@ batadv_mcast_mla_softif_get_ipv6(struct net_device *dev,
* the given mcast_list. In general, multicast listeners provided by * the given mcast_list. In general, multicast listeners provided by
* your multicast receiving applications run directly on this node. * your multicast receiving applications run directly on this node.
* *
* If there is a bridge interface on top of dev, collects from that one * If there is a bridge interface on top of dev, collect from that one
* instead. Just like with IP addresses and routes, multicast listeners * instead. Just like with IP addresses and routes, multicast listeners
* will(/should) register to the bridge interface instead of an * will(/should) register to the bridge interface instead of an
* enslaved bat0. * enslaved bat0.
...@@ -832,8 +832,8 @@ batadv_mcast_bridge_log(struct batadv_priv *bat_priv, ...@@ -832,8 +832,8 @@ batadv_mcast_bridge_log(struct batadv_priv *bat_priv,
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @flags: TVLV flags indicating the new multicast state * @flags: TVLV flags indicating the new multicast state
* *
* Whenever the multicast TVLV flags this nodes announces change this notifies * Whenever the multicast TVLV flags this node announces change, this function
* userspace via the 'mcast' log level. * should be used to notify userspace about the change.
*/ */
static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags) static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags)
{ {
...@@ -1244,7 +1244,7 @@ batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv) ...@@ -1244,7 +1244,7 @@ batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv)
* @ethhdr: an ethernet header to determine the protocol family from * @ethhdr: an ethernet header to determine the protocol family from
* *
* Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or * Return: an orig_node which has the BATADV_MCAST_WANT_ALL_IPV4 or
* BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, set and * BATADV_MCAST_WANT_ALL_IPV6 flag, depending on the provided ethhdr, sets and
* increases its refcount. * increases its refcount.
*/ */
static struct batadv_orig_node * static struct batadv_orig_node *
...@@ -1693,7 +1693,7 @@ batadv_mcast_forw_want_rtr(struct batadv_priv *bat_priv, ...@@ -1693,7 +1693,7 @@ batadv_mcast_forw_want_rtr(struct batadv_priv *bat_priv,
} }
/** /**
* batadv_mcast_forw_send() - send packet to any detected multicast recpient * batadv_mcast_forw_send() - send packet to any detected multicast recipient
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @skb: the multicast packet to transmit * @skb: the multicast packet to transmit
* @vid: the vlan identifier * @vid: the vlan identifier
...@@ -1742,7 +1742,8 @@ int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1742,7 +1742,8 @@ int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
* @mcast_flags: flags indicating the new multicast state * @mcast_flags: flags indicating the new multicast state
* *
* If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator, * If the BATADV_MCAST_WANT_ALL_UNSNOOPABLES flag of this originator,
* orig, has toggled then this method updates counter and list accordingly. * orig, has toggled then this method updates the counter and the list
* accordingly.
* *
* Caller needs to hold orig->mcast_handler_lock. * Caller needs to hold orig->mcast_handler_lock.
*/ */
...@@ -1787,7 +1788,7 @@ static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv, ...@@ -1787,7 +1788,7 @@ static void batadv_mcast_want_unsnoop_update(struct batadv_priv *bat_priv,
* @mcast_flags: flags indicating the new multicast state * @mcast_flags: flags indicating the new multicast state
* *
* If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has * If the BATADV_MCAST_WANT_ALL_IPV4 flag of this originator, orig, has
* toggled then this method updates counter and list accordingly. * toggled then this method updates the counter and the list accordingly.
* *
* Caller needs to hold orig->mcast_handler_lock. * Caller needs to hold orig->mcast_handler_lock.
*/ */
...@@ -1832,7 +1833,7 @@ static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv, ...@@ -1832,7 +1833,7 @@ static void batadv_mcast_want_ipv4_update(struct batadv_priv *bat_priv,
* @mcast_flags: flags indicating the new multicast state * @mcast_flags: flags indicating the new multicast state
* *
* If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has * If the BATADV_MCAST_WANT_ALL_IPV6 flag of this originator, orig, has
* toggled then this method updates counter and list accordingly. * toggled then this method updates the counter and the list accordingly.
* *
* Caller needs to hold orig->mcast_handler_lock. * Caller needs to hold orig->mcast_handler_lock.
*/ */
...@@ -1877,7 +1878,7 @@ static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv, ...@@ -1877,7 +1878,7 @@ static void batadv_mcast_want_ipv6_update(struct batadv_priv *bat_priv,
* @mcast_flags: flags indicating the new multicast state * @mcast_flags: flags indicating the new multicast state
* *
* If the BATADV_MCAST_WANT_NO_RTR4 flag of this originator, orig, has * If the BATADV_MCAST_WANT_NO_RTR4 flag of this originator, orig, has
* toggled then this method updates counter and list accordingly. * toggled then this method updates the counter and the list accordingly.
* *
* Caller needs to hold orig->mcast_handler_lock. * Caller needs to hold orig->mcast_handler_lock.
*/ */
...@@ -1922,7 +1923,7 @@ static void batadv_mcast_want_rtr4_update(struct batadv_priv *bat_priv, ...@@ -1922,7 +1923,7 @@ static void batadv_mcast_want_rtr4_update(struct batadv_priv *bat_priv,
* @mcast_flags: flags indicating the new multicast state * @mcast_flags: flags indicating the new multicast state
* *
* If the BATADV_MCAST_WANT_NO_RTR6 flag of this originator, orig, has * If the BATADV_MCAST_WANT_NO_RTR6 flag of this originator, orig, has
* toggled then this method updates counter and list accordingly. * toggled then this method updates the counter and the list accordingly.
* *
* Caller needs to hold orig->mcast_handler_lock. * Caller needs to hold orig->mcast_handler_lock.
*/ */
......
...@@ -640,7 +640,7 @@ batadv_netlink_tp_meter_put(struct sk_buff *msg, u32 cookie) ...@@ -640,7 +640,7 @@ batadv_netlink_tp_meter_put(struct sk_buff *msg, u32 cookie)
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @dst: destination of tp_meter session * @dst: destination of tp_meter session
* @result: reason for tp meter session stop * @result: reason for tp meter session stop
* @test_time: total time ot the tp_meter session * @test_time: total time of the tp_meter session
* @total_bytes: bytes acked to the receiver * @total_bytes: bytes acked to the receiver
* @cookie: cookie of tp_meter session * @cookie: cookie of tp_meter session
* *
...@@ -826,6 +826,10 @@ static int batadv_netlink_hardif_fill(struct sk_buff *msg, ...@@ -826,6 +826,10 @@ static int batadv_netlink_hardif_fill(struct sk_buff *msg,
goto nla_put_failure; goto nla_put_failure;
} }
if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY,
atomic_read(&hard_iface->hop_penalty)))
goto nla_put_failure;
#ifdef CONFIG_BATMAN_ADV_BATMAN_V #ifdef CONFIG_BATMAN_ADV_BATMAN_V
if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL, if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL,
atomic_read(&hard_iface->bat_v.elp_interval))) atomic_read(&hard_iface->bat_v.elp_interval)))
...@@ -920,9 +924,15 @@ static int batadv_netlink_set_hardif(struct sk_buff *skb, ...@@ -920,9 +924,15 @@ static int batadv_netlink_set_hardif(struct sk_buff *skb,
{ {
struct batadv_hard_iface *hard_iface = info->user_ptr[1]; struct batadv_hard_iface *hard_iface = info->user_ptr[1];
struct batadv_priv *bat_priv = info->user_ptr[0]; struct batadv_priv *bat_priv = info->user_ptr[0];
struct nlattr *attr;
if (info->attrs[BATADV_ATTR_HOP_PENALTY]) {
attr = info->attrs[BATADV_ATTR_HOP_PENALTY];
atomic_set(&hard_iface->hop_penalty, nla_get_u8(attr));
}
#ifdef CONFIG_BATMAN_ADV_BATMAN_V #ifdef CONFIG_BATMAN_ADV_BATMAN_V
struct nlattr *attr;
if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) { if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) {
attr = info->attrs[BATADV_ATTR_ELP_INTERVAL]; attr = info->attrs[BATADV_ATTR_ELP_INTERVAL];
......
...@@ -134,7 +134,7 @@ static void batadv_nc_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv, ...@@ -134,7 +134,7 @@ static void batadv_nc_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
} }
/** /**
* batadv_nc_mesh_init() - initialise coding hash table and start house keeping * batadv_nc_mesh_init() - initialise coding hash table and start housekeeping
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* *
* Return: 0 on success or negative error number in case of failure * Return: 0 on success or negative error number in case of failure
...@@ -700,7 +700,7 @@ batadv_nc_process_nc_paths(struct batadv_priv *bat_priv, ...@@ -700,7 +700,7 @@ batadv_nc_process_nc_paths(struct batadv_priv *bat_priv,
} }
/** /**
* batadv_nc_worker() - periodic task for house keeping related to network * batadv_nc_worker() - periodic task for housekeeping related to network
* coding * coding
* @work: kernel work struct * @work: kernel work struct
*/ */
...@@ -1316,7 +1316,7 @@ batadv_nc_path_search(struct batadv_priv *bat_priv, ...@@ -1316,7 +1316,7 @@ batadv_nc_path_search(struct batadv_priv *bat_priv,
} }
/** /**
* batadv_nc_skb_src_search() - Loops through the list of neighoring nodes of * batadv_nc_skb_src_search() - Loops through the list of neighboring nodes of
* the skb's sender (may be equal to the originator). * the skb's sender (may be equal to the originator).
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @skb: data skb to forward * @skb: data skb to forward
...@@ -1402,10 +1402,10 @@ static void batadv_nc_skb_store_before_coding(struct batadv_priv *bat_priv, ...@@ -1402,10 +1402,10 @@ static void batadv_nc_skb_store_before_coding(struct batadv_priv *bat_priv,
* @neigh_node: next hop to forward packet to * @neigh_node: next hop to forward packet to
* @ethhdr: pointer to the ethernet header inside the skb * @ethhdr: pointer to the ethernet header inside the skb
* *
* Loops through list of neighboring nodes the next hop has a good connection to * Loops through the list of neighboring nodes the next hop has a good
* (receives OGMs with a sufficient quality). We need to find a neighbor of our * connection to (receives OGMs with a sufficient quality). We need to find a
* next hop that potentially sent a packet which our next hop also received * neighbor of our next hop that potentially sent a packet which our next hop
* (overheard) and has stored for later decoding. * also received (overheard) and has stored for later decoding.
* *
* Return: true if the skb was consumed (encoded packet sent) or false otherwise * Return: true if the skb was consumed (encoded packet sent) or false otherwise
*/ */
......
...@@ -325,7 +325,7 @@ void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node) ...@@ -325,7 +325,7 @@ void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node)
* @if_outgoing: the interface where the payload packet has been received or * @if_outgoing: the interface where the payload packet has been received or
* the OGM should be sent to * the OGM should be sent to
* *
* Return: the neighbor which should be router for this orig_node/iface. * Return: the neighbor which should be the router for this orig_node/iface.
* *
* The object is returned with refcounter increased by 1. * The object is returned with refcounter increased by 1.
*/ */
...@@ -515,7 +515,7 @@ batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh, ...@@ -515,7 +515,7 @@ batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh,
* Looks for and possibly returns a neighbour belonging to this originator list * Looks for and possibly returns a neighbour belonging to this originator list
* which is connected through the provided hard interface. * which is connected through the provided hard interface.
* *
* Return: neighbor when found. Othwerwise NULL * Return: neighbor when found. Otherwise NULL
*/ */
static struct batadv_neigh_node * static struct batadv_neigh_node *
batadv_neigh_node_get(const struct batadv_orig_node *orig_node, batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
...@@ -620,7 +620,7 @@ batadv_hardif_neigh_get_or_create(struct batadv_hard_iface *hard_iface, ...@@ -620,7 +620,7 @@ batadv_hardif_neigh_get_or_create(struct batadv_hard_iface *hard_iface,
* *
* Looks for and possibly returns a neighbour belonging to this hard interface. * Looks for and possibly returns a neighbour belonging to this hard interface.
* *
* Return: neighbor when found. Othwerwise NULL * Return: neighbor when found. Otherwise NULL
*/ */
struct batadv_hardif_neigh_node * struct batadv_hardif_neigh_node *
batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface, batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
...@@ -999,7 +999,7 @@ void batadv_originator_free(struct batadv_priv *bat_priv) ...@@ -999,7 +999,7 @@ void batadv_originator_free(struct batadv_priv *bat_priv)
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @addr: the mac address of the originator * @addr: the mac address of the originator
* *
* Creates a new originator object and initialise all the generic fields. * Creates a new originator object and initialises all the generic fields.
* The new object is not added to the originator list. * The new object is not added to the originator list.
* *
* Return: the newly created object or NULL on failure. * Return: the newly created object or NULL on failure.
......
...@@ -449,7 +449,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, ...@@ -449,7 +449,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
* @skb: packet to check * @skb: packet to check
* @hdr_size: size of header to pull * @hdr_size: size of header to pull
* *
* Check for short header and bad addresses in given packet. * Checks for short header and bad addresses in the given packet.
* *
* Return: negative value when check fails and 0 otherwise. The negative value * Return: negative value when check fails and 0 otherwise. The negative value
* depends on the reason: -ENODATA for bad header, -EBADR for broadcast * depends on the reason: -ENODATA for bad header, -EBADR for broadcast
...@@ -1113,7 +1113,7 @@ int batadv_recv_unicast_tvlv(struct sk_buff *skb, ...@@ -1113,7 +1113,7 @@ int batadv_recv_unicast_tvlv(struct sk_buff *skb,
* @recv_if: interface that the skb is received on * @recv_if: interface that the skb is received on
* *
* This function does one of the three following things: 1) Forward fragment, if * This function does one of the three following things: 1) Forward fragment, if
* the assembled packet will exceed our MTU; 2) Buffer fragment, if we till * the assembled packet will exceed our MTU; 2) Buffer fragment, if we still
* lack further fragments; 3) Merge fragments, if we have all needed parts. * lack further fragments; 3) Merge fragments, if we have all needed parts.
* *
* Return: NET_RX_DROP if the skb is not consumed, NET_RX_SUCCESS otherwise. * Return: NET_RX_DROP if the skb is not consumed, NET_RX_SUCCESS otherwise.
......
...@@ -605,8 +605,8 @@ bool batadv_forw_packet_steal(struct batadv_forw_packet *forw_packet, ...@@ -605,8 +605,8 @@ bool batadv_forw_packet_steal(struct batadv_forw_packet *forw_packet,
* given hard_iface. If hard_iface is NULL forwarding packets on all hard * given hard_iface. If hard_iface is NULL forwarding packets on all hard
* interfaces will be claimed. * interfaces will be claimed.
* *
* The packets are being moved from the forw_list to the cleanup_list and * The packets are being moved from the forw_list to the cleanup_list. This
* by that allows already running threads to notice the claiming. * makes it possible for already running threads to notice the claim.
*/ */
static void static void
batadv_forw_packet_list_steal(struct hlist_head *forw_list, batadv_forw_packet_list_steal(struct hlist_head *forw_list,
......
...@@ -406,7 +406,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, ...@@ -406,7 +406,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
* @hdr_size: size of already parsed batman-adv header * @hdr_size: size of already parsed batman-adv header
* @orig_node: originator from which the batman-adv packet was sent * @orig_node: originator from which the batman-adv packet was sent
* *
* Sends a ethernet frame to the receive path of the local @soft_iface. * Sends an ethernet frame to the receive path of the local @soft_iface.
* skb->data has still point to the batman-adv header with the size @hdr_size. * skb->data has still point to the batman-adv header with the size @hdr_size.
* The caller has to have parsed this header already and made sure that at least * The caller has to have parsed this header already and made sure that at least
* @hdr_size bytes are still available for pull in @skb. * @hdr_size bytes are still available for pull in @skb.
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
/** /**
* BATADV_TP_MAX_RTO - Maximum sender timeout. If the sender RTO gets beyond * BATADV_TP_MAX_RTO - Maximum sender timeout. If the sender RTO gets beyond
* such amound of milliseconds, the receiver is considered unreachable and the * such amount of milliseconds, the receiver is considered unreachable and the
* connection is killed * connection is killed
*/ */
#define BATADV_TP_MAX_RTO 30000 #define BATADV_TP_MAX_RTO 30000
...@@ -108,10 +108,10 @@ static u32 batadv_tp_session_cookie(const u8 session[2], u8 icmp_uid) ...@@ -108,10 +108,10 @@ static u32 batadv_tp_session_cookie(const u8 session[2], u8 icmp_uid)
* batadv_tp_cwnd() - compute the new cwnd size * batadv_tp_cwnd() - compute the new cwnd size
* @base: base cwnd size value * @base: base cwnd size value
* @increment: the value to add to base to get the new size * @increment: the value to add to base to get the new size
* @min: minumim cwnd value (usually MSS) * @min: minimum cwnd value (usually MSS)
* *
* Return the new cwnd size and ensures it does not exceed the Advertised * Return the new cwnd size and ensure it does not exceed the Advertised
* Receiver Window size. It is wrap around safe. * Receiver Window size. It is wrapped around safely.
* For details refer to Section 3.1 of RFC5681 * For details refer to Section 3.1 of RFC5681
* *
* Return: new congestion window size in bytes * Return: new congestion window size in bytes
...@@ -254,7 +254,7 @@ static void batadv_tp_batctl_error_notify(enum batadv_tp_meter_reason reason, ...@@ -254,7 +254,7 @@ static void batadv_tp_batctl_error_notify(enum batadv_tp_meter_reason reason,
* @dst: the other endpoint MAC address to look for * @dst: the other endpoint MAC address to look for
* *
* Look for a tp_vars object matching dst as end_point and return it after * Look for a tp_vars object matching dst as end_point and return it after
* having incremented the refcounter. Return NULL is not found * having increment the refcounter. Return NULL is not found
* *
* Return: matching tp_vars or NULL when no tp_vars with @dst was found * Return: matching tp_vars or NULL when no tp_vars with @dst was found
*/ */
...@@ -291,7 +291,7 @@ static struct batadv_tp_vars *batadv_tp_list_find(struct batadv_priv *bat_priv, ...@@ -291,7 +291,7 @@ static struct batadv_tp_vars *batadv_tp_list_find(struct batadv_priv *bat_priv,
* @session: session identifier * @session: session identifier
* *
* Look for a tp_vars object matching dst as end_point, session as tp meter * Look for a tp_vars object matching dst as end_point, session as tp meter
* session and return it after having incremented the refcounter. Return NULL * session and return it after having increment the refcounter. Return NULL
* is not found * is not found
* *
* Return: matching tp_vars or NULL when no tp_vars was found * Return: matching tp_vars or NULL when no tp_vars was found
......
...@@ -301,7 +301,7 @@ void batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry) ...@@ -301,7 +301,7 @@ void batadv_tt_global_entry_put(struct batadv_tt_global_entry *tt_global_entry)
* @vid: VLAN identifier * @vid: VLAN identifier
* *
* Return: the number of originators advertising the given address/data * Return: the number of originators advertising the given address/data
* (excluding ourself). * (excluding our self).
*/ */
int batadv_tt_global_hash_count(struct batadv_priv *bat_priv, int batadv_tt_global_hash_count(struct batadv_priv *bat_priv,
const u8 *addr, unsigned short vid) const u8 *addr, unsigned short vid)
...@@ -842,7 +842,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr, ...@@ -842,7 +842,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
* table. In case of success the value is updated with the real amount of * table. In case of success the value is updated with the real amount of
* reserved bytes * reserved bytes
* Allocate the needed amount of memory for the entire TT TVLV and write its * Allocate the needed amount of memory for the entire TT TVLV and write its
* header made up by one tvlv_tt_data object and a series of tvlv_tt_vlan_data * header made up of one tvlv_tt_data object and a series of tvlv_tt_vlan_data
* objects, one per active VLAN served by the originator node. * objects, one per active VLAN served by the originator node.
* *
* Return: the size of the allocated buffer or 0 in case of failure. * Return: the size of the allocated buffer or 0 in case of failure.
...@@ -1674,7 +1674,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, ...@@ -1674,7 +1674,7 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
* the function argument. * the function argument.
* If a TT local entry exists for this non-mesh client remove it. * If a TT local entry exists for this non-mesh client remove it.
* *
* The caller must hold orig_node refcount. * The caller must hold the orig_node refcount.
* *
* Return: true if the new entry has been added, false otherwise * Return: true if the new entry has been added, false otherwise
*/ */
...@@ -1839,7 +1839,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv, ...@@ -1839,7 +1839,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @tt_global_entry: global translation table entry to be analyzed * @tt_global_entry: global translation table entry to be analyzed
* *
* This functon assumes the caller holds rcu_read_lock(). * This function assumes the caller holds rcu_read_lock().
* Return: best originator list entry or NULL on errors. * Return: best originator list entry or NULL on errors.
*/ */
static struct batadv_tt_orig_list_entry * static struct batadv_tt_orig_list_entry *
...@@ -1887,7 +1887,7 @@ batadv_transtable_best_orig(struct batadv_priv *bat_priv, ...@@ -1887,7 +1887,7 @@ batadv_transtable_best_orig(struct batadv_priv *bat_priv,
* @tt_global_entry: global translation table entry to be printed * @tt_global_entry: global translation table entry to be printed
* @seq: debugfs table seq_file struct * @seq: debugfs table seq_file struct
* *
* This functon assumes the caller holds rcu_read_lock(). * This function assumes the caller holds rcu_read_lock().
*/ */
static void static void
batadv_tt_global_print_entry(struct batadv_priv *bat_priv, batadv_tt_global_print_entry(struct batadv_priv *bat_priv,
......
...@@ -353,8 +353,8 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv, ...@@ -353,8 +353,8 @@ u16 batadv_tvlv_container_ogm_append(struct batadv_priv *bat_priv,
* @tvlv_value: tvlv content * @tvlv_value: tvlv content
* @tvlv_value_len: tvlv content length * @tvlv_value_len: tvlv content length
* *
* Return: success if handler was not found or the return value of the handler * Return: success if the handler was not found or the return value of the
* callback. * handler callback.
*/ */
static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv, static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,
struct batadv_tvlv_handler *tvlv_handler, struct batadv_tvlv_handler *tvlv_handler,
......
...@@ -208,6 +208,12 @@ struct batadv_hard_iface { ...@@ -208,6 +208,12 @@ struct batadv_hard_iface {
/** @rcu: struct used for freeing in an RCU-safe manner */ /** @rcu: struct used for freeing in an RCU-safe manner */
struct rcu_head rcu; struct rcu_head rcu;
/**
* @hop_penalty: penalty which will be applied to the tq-field
* of an OGM received via this interface
*/
atomic_t hop_penalty;
/** @bat_iv: per hard-interface B.A.T.M.A.N. IV data */ /** @bat_iv: per hard-interface B.A.T.M.A.N. IV data */
struct batadv_hard_iface_bat_iv bat_iv; struct batadv_hard_iface_bat_iv bat_iv;
...@@ -455,8 +461,8 @@ struct batadv_orig_node { ...@@ -455,8 +461,8 @@ struct batadv_orig_node {
spinlock_t tt_buff_lock; spinlock_t tt_buff_lock;
/** /**
* @tt_lock: prevents from updating the table while reading it. Table * @tt_lock: avoids concurrent read from and write to the table. Table
* update is made up by two operations (data structure update and * update is made up of two operations (data structure update and
* metadata -CRC/TTVN-recalculation) and they have to be executed * metadata -CRC/TTVN-recalculation) and they have to be executed
* atomically in order to avoid another thread to read the * atomically in order to avoid another thread to read the
* table/metadata between those. * table/metadata between those.
...@@ -748,7 +754,7 @@ struct batadv_neigh_ifinfo { ...@@ -748,7 +754,7 @@ struct batadv_neigh_ifinfo {
* struct batadv_bcast_duplist_entry - structure for LAN broadcast suppression * struct batadv_bcast_duplist_entry - structure for LAN broadcast suppression
*/ */
struct batadv_bcast_duplist_entry { struct batadv_bcast_duplist_entry {
/** @orig: mac address of orig node orginating the broadcast */ /** @orig: mac address of orig node originating the broadcast */
u8 orig[ETH_ALEN]; u8 orig[ETH_ALEN];
/** @crc: crc32 checksum of broadcast payload */ /** @crc: crc32 checksum of broadcast payload */
...@@ -1010,7 +1016,7 @@ struct batadv_priv_tt { ...@@ -1010,7 +1016,7 @@ struct batadv_priv_tt {
/** /**
* @commit_lock: prevents from executing a local TT commit while reading * @commit_lock: prevents from executing a local TT commit while reading
* the local table. The local TT commit is made up by two operations * the local table. The local TT commit is made up of two operations
* (data structure update and metadata -CRC/TTVN- recalculation) and * (data structure update and metadata -CRC/TTVN- recalculation) and
* they have to be executed atomically in order to avoid another thread * they have to be executed atomically in order to avoid another thread
* to read the table/metadata between those. * to read the table/metadata between those.
...@@ -1024,7 +1030,7 @@ struct batadv_priv_tt { ...@@ -1024,7 +1030,7 @@ struct batadv_priv_tt {
#ifdef CONFIG_BATMAN_ADV_BLA #ifdef CONFIG_BATMAN_ADV_BLA
/** /**
* struct batadv_priv_bla - per mesh interface bridge loope avoidance data * struct batadv_priv_bla - per mesh interface bridge loop avoidance data
*/ */
struct batadv_priv_bla { struct batadv_priv_bla {
/** @num_requests: number of bla requests in flight */ /** @num_requests: number of bla requests in flight */
...@@ -1718,7 +1724,7 @@ struct batadv_priv { ...@@ -1718,7 +1724,7 @@ struct batadv_priv {
spinlock_t softif_vlan_list_lock; spinlock_t softif_vlan_list_lock;
#ifdef CONFIG_BATMAN_ADV_BLA #ifdef CONFIG_BATMAN_ADV_BLA
/** @bla: bridge loope avoidance data */ /** @bla: bridge loop avoidance data */
struct batadv_priv_bla bla; struct batadv_priv_bla bla;
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment