Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8eb9bff0 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'batman-adv-fix-for-davem' of git://git.open-mesh.org/linux-merge



Included changes:

- reset netfilter-bridge state when removing the batman-adv
  header from an incoming packet. This prevents netfilter
  bridge from being fooled when the same packet enters a
  bridge twice (or more): the first time within the
  batman-adv header and the second time without.

- adjust the packet layout to prevent any architecture from
  adding padding bytes. All the structs sent over the wire
  now have size multiple of 4bytes (unless pack(2) is used).

- fix access to the inner vlan_eth header when reading the
  VID in the rx path.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a72338a0 2b1e2cb3
Loading
Loading
Loading
Loading
+18 −18
Original line number Diff line number Diff line
@@ -307,9 +307,9 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
	hard_iface->bat_iv.ogm_buff = ogm_buff;

	batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
	batadv_ogm_packet->header.packet_type = BATADV_IV_OGM;
	batadv_ogm_packet->header.version = BATADV_COMPAT_VERSION;
	batadv_ogm_packet->header.ttl = 2;
	batadv_ogm_packet->packet_type = BATADV_IV_OGM;
	batadv_ogm_packet->version = BATADV_COMPAT_VERSION;
	batadv_ogm_packet->ttl = 2;
	batadv_ogm_packet->flags = BATADV_NO_FLAGS;
	batadv_ogm_packet->reserved = 0;
	batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
@@ -346,7 +346,7 @@ batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)

	batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
	batadv_ogm_packet->flags = BATADV_PRIMARIES_FIRST_HOP;
	batadv_ogm_packet->header.ttl = BATADV_TTL;
	batadv_ogm_packet->ttl = BATADV_TTL;
}

/* when do we schedule our own ogm to be sent */
@@ -435,7 +435,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
			   fwd_str, (packet_num > 0 ? "aggregated " : ""),
			   batadv_ogm_packet->orig,
			   ntohl(batadv_ogm_packet->seqno),
			   batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl,
			   batadv_ogm_packet->tq, batadv_ogm_packet->ttl,
			   (batadv_ogm_packet->flags & BATADV_DIRECTLINK ?
			    "on" : "off"),
			   hard_iface->net_dev->name,
@@ -491,7 +491,7 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
	/* multihomed peer assumed
	 * non-primary OGMs are only broadcasted on their interface
	 */
	if ((directlink && (batadv_ogm_packet->header.ttl == 1)) ||
	if ((directlink && (batadv_ogm_packet->ttl == 1)) ||
	    (forw_packet->own && (forw_packet->if_incoming != primary_if))) {
		/* FIXME: what about aggregated packets ? */
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
@@ -499,7 +499,7 @@ static void batadv_iv_ogm_emit(struct batadv_forw_packet *forw_packet)
			   (forw_packet->own ? "Sending own" : "Forwarding"),
			   batadv_ogm_packet->orig,
			   ntohl(batadv_ogm_packet->seqno),
			   batadv_ogm_packet->header.ttl,
			   batadv_ogm_packet->ttl,
			   forw_packet->if_incoming->net_dev->name,
			   forw_packet->if_incoming->net_dev->dev_addr);

@@ -572,7 +572,7 @@ batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
		 */
		if ((!directlink) &&
		    (!(batadv_ogm_packet->flags & BATADV_DIRECTLINK)) &&
		    (batadv_ogm_packet->header.ttl != 1) &&
		    (batadv_ogm_packet->ttl != 1) &&

		    /* own packets originating non-primary
		     * interfaces leave only that interface
@@ -587,7 +587,7 @@ batadv_iv_ogm_can_aggregate(const struct batadv_ogm_packet *new_bat_ogm_packet,
		 * interface only - we still can aggregate
		 */
		if ((directlink) &&
		    (new_bat_ogm_packet->header.ttl == 1) &&
		    (new_bat_ogm_packet->ttl == 1) &&
		    (forw_packet->if_incoming == if_incoming) &&

		    /* packets from direct neighbors or
@@ -778,7 +778,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
	struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
	uint16_t tvlv_len;

	if (batadv_ogm_packet->header.ttl <= 1) {
	if (batadv_ogm_packet->ttl <= 1) {
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "ttl exceeded\n");
		return;
	}
@@ -798,7 +798,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,

	tvlv_len = ntohs(batadv_ogm_packet->tvlv_len);

	batadv_ogm_packet->header.ttl--;
	batadv_ogm_packet->ttl--;
	memcpy(batadv_ogm_packet->prev_sender, ethhdr->h_source, ETH_ALEN);

	/* apply hop penalty */
@@ -807,7 +807,7 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,

	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
		   "Forwarding packet: tq: %i, ttl: %i\n",
		   batadv_ogm_packet->tq, batadv_ogm_packet->header.ttl);
		   batadv_ogm_packet->tq, batadv_ogm_packet->ttl);

	/* switch of primaries first hop flag when forwarding */
	batadv_ogm_packet->flags &= ~BATADV_PRIMARIES_FIRST_HOP;
@@ -972,8 +972,8 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
	spin_unlock_bh(&neigh_node->bat_iv.lq_update_lock);

	if (dup_status == BATADV_NO_DUP) {
		orig_node->last_ttl = batadv_ogm_packet->header.ttl;
		neigh_node->last_ttl = batadv_ogm_packet->header.ttl;
		orig_node->last_ttl = batadv_ogm_packet->ttl;
		neigh_node->last_ttl = batadv_ogm_packet->ttl;
	}

	batadv_bonding_candidate_add(bat_priv, orig_node, neigh_node);
@@ -1247,7 +1247,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
	 * packet in an aggregation.  Here we expect that the padding
	 * is always zero (or not 0x01)
	 */
	if (batadv_ogm_packet->header.packet_type != BATADV_IV_OGM)
	if (batadv_ogm_packet->packet_type != BATADV_IV_OGM)
		return;

	/* could be changed by schedule_own_packet() */
@@ -1267,8 +1267,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
		   if_incoming->net_dev->dev_addr, batadv_ogm_packet->orig,
		   batadv_ogm_packet->prev_sender,
		   ntohl(batadv_ogm_packet->seqno), batadv_ogm_packet->tq,
		   batadv_ogm_packet->header.ttl,
		   batadv_ogm_packet->header.version, has_directlink_flag);
		   batadv_ogm_packet->ttl,
		   batadv_ogm_packet->version, has_directlink_flag);

	rcu_read_lock();
	list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
@@ -1433,7 +1433,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
	 * seqno and similar ttl as the non-duplicate
	 */
	sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno);
	similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl;
	similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->ttl;
	if (is_bidirect && ((dup_status == BATADV_NO_DUP) ||
			    (sameseq && similar_ttl)))
		batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr,
+3 −3
Original line number Diff line number Diff line
@@ -349,7 +349,7 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,

	unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;

	switch (unicast_4addr_packet->u.header.packet_type) {
	switch (unicast_4addr_packet->u.packet_type) {
	case BATADV_UNICAST:
		batadv_dbg(BATADV_DBG_DAT, bat_priv,
			   "* encapsulated within a UNICAST packet\n");
@@ -374,7 +374,7 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,
			break;
		default:
			batadv_dbg(BATADV_DBG_DAT, bat_priv, "* type: Unknown (%u)!\n",
				   unicast_4addr_packet->u.header.packet_type);
				   unicast_4addr_packet->u.packet_type);
		}
		break;
	case BATADV_BCAST:
@@ -387,7 +387,7 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb,
	default:
		batadv_dbg(BATADV_DBG_DAT, bat_priv,
			   "* encapsulated within an unknown packet type (0x%x)\n",
			   unicast_4addr_packet->u.header.packet_type);
			   unicast_4addr_packet->u.packet_type);
	}
}

+4 −4
Original line number Diff line number Diff line
@@ -355,7 +355,7 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,
		batadv_add_counter(bat_priv, BATADV_CNT_FRAG_FWD_BYTES,
				   skb->len + ETH_HLEN);

		packet->header.ttl--;
		packet->ttl--;
		batadv_send_skb_packet(skb, neigh_node->if_incoming,
				       neigh_node->addr);
		ret = true;
@@ -444,9 +444,9 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
		goto out_err;

	/* Create one header to be copied to all fragments */
	frag_header.header.packet_type = BATADV_UNICAST_FRAG;
	frag_header.header.version = BATADV_COMPAT_VERSION;
	frag_header.header.ttl = BATADV_TTL;
	frag_header.packet_type = BATADV_UNICAST_FRAG;
	frag_header.version = BATADV_COMPAT_VERSION;
	frag_header.ttl = BATADV_TTL;
	frag_header.seqno = htons(atomic_inc_return(&bat_priv->frag_seqno));
	frag_header.reserved = 0;
	frag_header.no = 0;
+3 −3
Original line number Diff line number Diff line
@@ -194,7 +194,7 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,
		goto free_skb;
	}

	if (icmp_header->header.packet_type != BATADV_ICMP) {
	if (icmp_header->packet_type != BATADV_ICMP) {
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
		len = -EINVAL;
@@ -243,9 +243,9 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff,

	icmp_header->uid = socket_client->index;

	if (icmp_header->header.version != BATADV_COMPAT_VERSION) {
	if (icmp_header->version != BATADV_COMPAT_VERSION) {
		icmp_header->msg_type = BATADV_PARAMETER_PROBLEM;
		icmp_header->header.version = BATADV_COMPAT_VERSION;
		icmp_header->version = BATADV_COMPAT_VERSION;
		batadv_socket_add_packet(socket_client, icmp_header,
					 packet_len);
		goto free_skb;
+8 −8
Original line number Diff line number Diff line
@@ -383,17 +383,17 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,

	batadv_ogm_packet = (struct batadv_ogm_packet *)skb->data;

	if (batadv_ogm_packet->header.version != BATADV_COMPAT_VERSION) {
	if (batadv_ogm_packet->version != BATADV_COMPAT_VERSION) {
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
			   "Drop packet: incompatible batman version (%i)\n",
			   batadv_ogm_packet->header.version);
			   batadv_ogm_packet->version);
		goto err_free;
	}

	/* all receive handlers return whether they received or reused
	 * the supplied skb. if not, we have to free the skb.
	 */
	idx = batadv_ogm_packet->header.packet_type;
	idx = batadv_ogm_packet->packet_type;
	ret = (*batadv_rx_handler[idx])(skb, hard_iface);

	if (ret == NET_RX_DROP)
@@ -426,8 +426,8 @@ static void batadv_recv_handler_init(void)
	BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4);
	BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4);
	BUILD_BUG_ON(offsetof(struct batadv_frag_packet, dest) != 4);
	BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, icmph.dst) != 4);
	BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, icmph.dst) != 4);
	BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, dst) != 4);
	BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, dst) != 4);

	/* broadcast packet */
	batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet;
@@ -1119,9 +1119,9 @@ void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, uint8_t *src,
	skb_reserve(skb, ETH_HLEN);
	tvlv_buff = skb_put(skb, sizeof(*unicast_tvlv_packet) + tvlv_len);
	unicast_tvlv_packet = (struct batadv_unicast_tvlv_packet *)tvlv_buff;
	unicast_tvlv_packet->header.packet_type = BATADV_UNICAST_TVLV;
	unicast_tvlv_packet->header.version = BATADV_COMPAT_VERSION;
	unicast_tvlv_packet->header.ttl = BATADV_TTL;
	unicast_tvlv_packet->packet_type = BATADV_UNICAST_TVLV;
	unicast_tvlv_packet->version = BATADV_COMPAT_VERSION;
	unicast_tvlv_packet->ttl = BATADV_TTL;
	unicast_tvlv_packet->reserved = 0;
	unicast_tvlv_packet->tvlv_len = htons(tvlv_len);
	unicast_tvlv_packet->align = 0;
Loading