net/batman-adv/bat_v_ogm.c

Source file repositories/reference/linux-study-clean/net/batman-adv/bat_v_ogm.c

File Facts

System
Linux kernel
Corpus path
net/batman-adv/bat_v_ogm.c
Extension
.c
Size
33876 bytes
Lines
1094
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret) {
			char *type;

			switch (ret) {
			case BATADV_HARDIF_BCAST_NORECIPIENT:
				type = "no neighbor";
				break;
			case BATADV_HARDIF_BCAST_DUPFWD:
				type = "single neighbor is source";
				break;
			case BATADV_HARDIF_BCAST_DUPORIG:
				type = "single neighbor is originator";
				break;
			default:
				type = "unknown";
			}

			batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "OGM2 from ourselves on %s suppressed: %s\n",
				   hard_iface->net_dev->name, type);

			batadv_hardif_put(hard_iface);
			continue;
		}

		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Sending own OGM2 packet (originator %pM, seqno %u, throughput %u, TTL %d) on interface %s [%pM]\n",
			   ogm_packet->orig, ntohl(ogm_packet->seqno),
			   ntohl(ogm_packet->throughput), ogm_packet->ttl,
			   hard_iface->net_dev->name,
			   hard_iface->net_dev->dev_addr);

		/* this skb gets consumed by batadv_v_ogm_send_to_if() */
		skb_tmp = skb_clone(skb, GFP_ATOMIC);
		if (!skb_tmp) {
			batadv_hardif_put(hard_iface);
			break;
		}

		batadv_v_ogm_queue_on_if(bat_priv, skb_tmp, hard_iface);
		batadv_hardif_put(hard_iface);
	}
	rcu_read_unlock();

	consume_skb(skb);

reschedule:
	batadv_v_ogm_start_timer(bat_priv);
out:
	return;
}

/**
 * batadv_v_ogm_send() - periodic worker broadcasting the own OGM
 * @work: work queue item
 */
static void batadv_v_ogm_send(struct work_struct *work)
{
	struct batadv_priv_bat_v *bat_v;
	struct batadv_priv *bat_priv;

	bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
	bat_priv = container_of(bat_v, struct batadv_priv, bat_v);

	mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
	batadv_v_ogm_send_meshif(bat_priv);
	mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
}

/**
 * batadv_v_ogm_aggr_work() - OGM queue periodic task per interface
 * @work: work queue item
 *
 * Emits aggregated OGM messages in regular intervals.
 */
void batadv_v_ogm_aggr_work(struct work_struct *work)
{
	struct batadv_hard_iface_bat_v *batv;
	struct batadv_hard_iface *hard_iface;
	struct batadv_priv *bat_priv;

	batv = container_of(work, struct batadv_hard_iface_bat_v, aggr_wq.work);
	hard_iface = container_of(batv, struct batadv_hard_iface, bat_v);
	bat_priv = netdev_priv(hard_iface->mesh_iface);

	spin_lock_bh(&hard_iface->bat_v.aggr_list.lock);
	batadv_v_ogm_aggr_send(bat_priv, hard_iface);
	spin_unlock_bh(&hard_iface->bat_v.aggr_list.lock);

	batadv_v_ogm_start_queue_timer(hard_iface);
}

Annotation

Implementation Notes